查看原文
其他

从码农到大牛,如何做到技术与心境的双重提升?

2017-12-23 张亮 51CTO技术栈

来自当当架构部的张亮老师,从技术和情怀的角度分享自己的成长轨迹,具备工匠精神的同时也要注重回报社会,做到技术与心境双重提升。


业务功能关注点


对于一个做技术的从业人员来说,大部分人开始走的是一条技术+业务的线路。


从业务功能方面回顾一下工程师工作的大致内容:

  • 业务理解和分析,通过解读需求文档,理解并分析业务。

  • UML 建模,将对业务的理解抽象和归纳为领域模型,并通过绘制 UML 展现。

  • 数据库表结构设计,大部分应用程序都是有数据库的。在设计过程中,有人喜欢先设计数据库表结构,再创建域模型,也可以反过来,习惯而已。

  • 选择合适的开发框架,在表结构设计完毕之后,就会选择或搭建合适的开发框架,然后进入开发阶段。基础框架采用分层模型居多,选用 ssh 或 ssi 等流行的框架比较常见。


随着经验越来越丰富,工程师的关注点从功能需求逐渐扩展到了非功能需求。功能的满足只是冰山浮在水面上的一小块。


而冰山下面的的巨大沉积物则是非功能需求,它们经常被非技术从业人员所忽视,但却是实实在在地影响一个系统成功与否的关键。


非功能需求关注点


非功能需求有如下四个关注点:

  • 安全性,有无 SQL 注入和跨域脚本攻击的问题;密码是否明文在网络间传输;是否可通过主键推算出其他主键并达到非法访问的目的(如:ID 是连续的,只要知道一个 ID,就可能获取到其他人的信息)。

  • 健壮性,程序是否由于异常情况导致崩溃,性能是否稳定(如:锁的不正确使用导致等待过多)等。

  • 可伸缩性,业务成长初期和业务爆发性增长期的应用承载量是完全不同的。当业务快速增长,应用承载量大幅度提升时,如何通过增加服务器数量的水平扩展而不是增加单一服务器硬件配置的垂直扩展来达到承载更多流量和数据量的目的,并且可以在流量洪峰平稳度过后适当的减少硬件服务器来控制成本。

  • 可维护性,在需要人工介入的系统部署流程中,失误无法完全避免。并且由于网络抖动而需要运维或重启时,大量的手工操作难免手忙脚乱,极易产生操作延迟。应通过自动化调度以及部署来帮助运维工程师尽量降低人工介入的频度。


在成长的轨迹中,工程师大多从微观入手,并最终领悟如何从宏观看待技术。


成长轨迹:微观关注点


几个常见的微观关注点:

  • 如何对慢 SQL 创建索引?相信工程师们应该都做过这件事,分析 SQL 执行计划,查看索引命中情况等。

  • 如何保证线程安全?单线程时没有问题,但多线程时则可能产生莫名其妙的问题。如何在多线程中合理的使用 synchronized,volatile 以及并发包等,是重要且困难的。

    并不是不写多线程代码就能完全规避这些问题。若使用的框架包括多线程,也需要使用者理解它的线程模型。

  • 如何减少 Full GC 的频度?一个跑在 JVM 里面的程序,如果每小时做一次 Full GC 导致应用停止响应一秒的时间,在性能以及并发要求较高的系统中是难以接受的。需要通过 JVM 调优来降低 Full GC 频度。

  • 如何考虑使用设计模式?设计模式是发现而非发明出来的,目前设计模式已经归纳的很成熟了,已不太容易再发现新设计模式。利用设计模式可以更好的写出结构清晰,易于理解的代码,并降低相互的沟通成本。

  • 如何写出具备强表现力的代码?若代码本身难以理解,即使通过注释也难于让代码本身具有表现力。而且代码和注释也不一定是同步修改的。

    着急改代码,但注释没有改的情况比较常见,这样的注释是没有价值的,不如花些时间让代码本身更具展现力。


成长轨迹:宏观关注点


随着时间的推移以及经验的累积,工程师会渐渐地关注更加宏观的方面,例如:


如何选用适合数据库存储相应的数据?


对于存储订单、交易等核心数据,稳定成熟的关系型数据库是不二之选;对于存储帖子类的文本数据, ES 就会更加合适。


因此需要工程师了解各种数据库的适合场景,结合上下文分析并最终确定选型。


如何规划系统范围的划分和拆分?


规模较大公司的系统不可能仅有一个或几个,它们也不会将所有的服务全部部署在同一个应用服务器中,而是将其拆分为几十、几百甚至上千个系统。


无论是当前较为流行的微服务架构,还是以前提及较多的 SOA 架构,都需要对系统进行拆分。


如何合理划分系统的范围是宏观思考的范畴,如:一个需求应该放入哪个系统,多个需求是否是独立组成的新系统等。


如何规范系统间的同步异步通讯方式?


系统增多,则需要考虑系统间的通信交互方式。通信有 RPC 或 RESTful 的同步访问方式,也有通过消息中间件的异步访问方式。


定义各种交互的规范,如:确定采用同步通信以及异步通信的标准;确定采用明文、二进制以及加密自定义序列化协议的场景。


分布式系统高可用以及伸缩性如何保障?


分布式系统和单机系统最大的区别在于分布式的不确定性,每次远程调用的请求是否到达难于保证。


单机系统宕机,会导致整个系统不可用,但尽力去维护一个单一的系统难度并不大。而分布式系统出现最多的场景是一部分服务宕机,其余的大部分服务仍然正常。


在系统很多的情况下,其排列组合的可能性是指数级上升的。如何能在这种情况下,保证系统的可用性以及伸缩性,是需要从宏观点考虑的。如:是否需要有服务治理系统,如何监控,何时扩容等。


如何考虑资源、调度、运维、监控一体化?


在容器、云计算发展的较为成熟的今天,基于 Mesos、K8S、Swarm 等平台提供资源分配 +调度+部署的一体化平台已不是难事。


比如,现在有一个由 2 台 4 核服务器组成的8核小集群,运行一个任务只占用 0.5 核 CPU,如果该任务占用整个一台服务器,资源利用率是很低的,因此需要考虑资源的合理分配和调度。


一旦某台服务器宕机,应将该服务器中运行的任务分配到另一台服务器中,这个过程应尽量自动化。


以上简单聊了一些技术人员随着经验和技能的增长发生的客观变化。工作内容会从仅关心业务功能转变为同时关注非功能需求,思维方式也会经历从微观到宏观的大局观演进。


接下来聊一聊主观方面的东西,从工匠精神开始谈起。


工匠精神


工匠精神是什么?


借用日本剑道三个字——“守破离”。它对其他行业也有借鉴意义,对从事技术行业的同事来说,可以这样解读:


守——钻研基础知识、理解经典理论、熟悉各种轮子


首先,应充分了解技术的现状。现在的各种技术栈已经趋于完善,应该多了解、多体会、多学习,多思考。


尽量多的理解经典理论,比如,CAP 理论是在说明什么问题,BASE 的最终一致性该怎么做。


基于 PAXOS 和 ZAB 协议做的 ZooKeeper 适用于什么场景,Raft 和他们又有什么异同;ACID 的强事务又应该用在何处等。


理解经典理论的同时,再熟悉各种各样的轮子。这时不应急于考虑自己应该重新做什么,如果没有熟练的使用 Spring Framework,理解它的依赖注入和控制反转理念,直接做一个超越它的框架又谈何容易。


破——尝试修改框架源码,总结自己的最佳实践


通过学习钻研,已逐渐的形成自己的独立知识体系。对一些技术通用性不强,但行业通用性较强的问题,可以自己写框架,或者改写优秀框架的源码,吸收其精华,彻底转化为自己的知识。


通过总结自己独特的最佳实践,慢慢的找到一条适合自己的道路,这不仅限于技术,也包括管理、做事方式等方面。


离——抛开束缚,开辟新境界


这个境界很多人终其一生也很难达到。触摸到这个境界之时,可以将一切的束缚都抛开,根据自己的经验和能力,顺势而为的完成一些作品,独立地创造一些东西,可以是技术产品,也可以是服务,更可以是创业的公司。


概括来说:

  • 守,刚到公司,熟悉自己的工作,积累经验。

  • 破,在团队中负责核心工作,根据自己的知识制定规范,领导他人。

  • 离,可遇而不可求,创造更大的价值。


举例来说, Linux、MySQL、Hadoop 这种级别产品所谓的神级人物,他们所做的不仅仅是一个产品,而是一个时代。


技术并不简单,无论是深度还是广度,都存在极大的纵深。想真正的成长为大牛,应该要遵循工匠精神,产生足够敬意,因为接下来会有一条很长的路要走。


成长必要条件


兴趣


只有保持足够的兴趣才能在技术上走得更远。如果做技术无法体会快乐,完全是为了养家糊口而被迫走上这条路,相信很难在漫长的职业生涯中有足够的动力持续成长。


世界很精彩,不喜欢做技术的人不一定非要做技术,如果最终一定要转行,越早就越能在新的行业中掌握主动权。


决心


对技术有兴趣是先决条件,但并不是仅通过兴趣,随随便便的学习和提高,就一定能成为技术大牛。当然不排除有的人天赋较高,成为技术大牛的路径会稍微轻松一点。


技术这个领域与变化相对少的领域不同,一年前的大牛,由于跟不上剧烈的技术变化而快速出局的可能性也是有的。因此想保持长期的竞争力,持续学习和提高决心是很重要的因素。


毅力


一旦下了决心就要持续的提高自己,这是一个长期积累的过程,需要有足够的毅力坚持。最终的一蹴而就,需要各方面的积累和融会贯通。


想成为大牛的一个先决条件,一定是有想成为大牛的强烈愿望。这个道理与不想当将军的士兵不是一个好的士兵是一样的。


如果本人都没愿望、没信心、没兴趣,自己都不朝着这个目标努力,他不太可能被动的被成长为一个大牛。


从“守破离”三点来看,被推动,即使平台再优秀,能走到“破”这一阶段已经是极限了,能走到“离”阶段的人,是通过的兴趣、决心和毅力主动达到的。


一些建议


这里特别澄清一下,我没有任何倾向表达转岗不好,任何岗位和行业都有其独特的价值,行行出状元,这里仅仅是对开发岗朋友的一些建议。


优质完成工作


毕竟工作还是很重要的,而且只有工作这个平台,给人带来的促进和成长才是最大的。


不能因为只对纯技术感兴趣,而对工作中的业务完全没兴趣,就不尽力做,不用心思考,脱离业务的技术本身并不会产生价值。


保持对技术的热情


有的朋友在接触一个新技术一段时间之后,完全掌握了使用问题,虽然也可能吐槽某些方面用起来不顺手,但并不深究其原理,也不动手改进,一直停留在使用阶段,用它做做业务,把工作完成。


这种类型的人如果继续做技术,未来难免会遇到瓶颈,从而失去自己的核心竞争力,尽早转管理、业务或产品甚至测试都是可以的。


目前新概念层出不穷,当前的热点技术过段时间也许就不再流行,因此养成长期关注技术趋势,保持敏感度也很重要。


完成一个基于兴趣的作品


将一个作品当做艺术品去做,不考虑排期、取舍,而是尽自己最大的努力,一点点的打磨,螺旋形的提升它的代码和功能。


当完成了一个与工作无关,只因兴趣打造的作品完成之后,一定能从中获取很多经验,带来很大成长。


维持开放的心态


无论自己的水平成长的有多高、多快,个人的精力有限,永远不可能了解和认知所有的技术和知识。


因此仍旧需要随时维持开放的心态,多交流、沟通、学习,充实自己。


开源、分享、回馈社区


做开源,让其他工程师研究你写的代码,或在各种平台分享自己的经验,以及积极的回馈社区,包括回答问题,对开源产品提交 issue、提交 pr、撰写文档、编写使用心得等。


做这些看似不能直接带来收益的事情,经过积累之后所获取的收益不仅是能力提升,也会对技术影响力带来提升,并且有更多的机会与更多的牛人交流。


成长的目标


专业性的态度


以两个技术问题聊聊专业性的态度:


框架是设计出来的还是演进出来的?


这其实是一个开放性问题,不同习惯的人,他们的回答也许不一样。我认为优秀的设计可以少走一些弯路,但一个长久不衰的框架,一定是经过层层演进而来。


如大家熟悉的 Spring Framework,已发展到了 Spring 5.X,Spring 1X 和 Spring 5.X 差别很大。


在其长期的演变过程中,层出不穷的出现了很多新技术,它为了适配一步步的进行演进,直至现在。


所以,需要一个专业性的态度,让自己的产品可以持续演进。


如何精炼一个模块?


去观察一个存在时间较长的活跃项目的提交记录,代码的增加和删除行数基本成正比,有效的删除无用代码的重要程度和新功能开发相当。


如果是观察一个试水性质的项目的提交记录则另当别论,基本上代码只增不删。因此,精炼一个模块,要持续对它进行修改和完善,它才能以螺旋型的方式去提升。


前瞻性的眼光


架构是设计出来的还是演进出来的?


如果刚才的问题是开放性的,那么这个问题并不能算是开放性的。我认为好的架构一定是设计出来而非演进而来的。


如果架构一开始并没有设计的足够好,而是随着系统的演进,架构也在与时俱进的演进。


那么架构和业务的双重修改所带来的复杂性和不确定性是难以估量的,而且架构所能提供的能力决定了业务代码的上限。不具备前瞻性的架构是失败的作品。


设计一个架构,是在设计一个世界还是实现一个细节?


这个问题的答案显而易见。所谓架构,最先出现于建筑学,架构相当于一个房屋的梁与柱,用于 IT 行业,架构同样相当于一个系统的基础设施。


因此设计一个架构,是大方向的规划和演进路径的阐述,而非细节的实现和优化。


颠覆一个架构的损失会有多大?


不到万不得已,企业不会轻易更换开发语言和数据库。同样,更换架构也是实在撑不下去才为之。


因此大部分时间,工程师都是在一个已经相对过时的架构中开发,那么架构设计的是否有前瞻性,是否最大限度的灵活拥抱变化、满足性能要求就更加重要。


系统性的思考


方案如何落地?


完成一个方案之后,让其落地并不简单,如何部署、运维、调试、灰度升级、回滚都是需要考虑的范畴。这是一个整体落地的过程,一个整体思维上的闭环。


代码提交了就是全部吗?


刚才提到的方案落地话题比较大,换一个小一点的话题。技术人员主要以写代码为主,代码提交只是工作的一部分,剩余的工作量还有很多。


比如怎么交接、文档是否易懂、如何修复 Bug 等一系列相关问题。同样需要培养一个整体的、系统的思考能力。


心境转换



在完成技术层面的提升外,还需要有心境上的转换。主要包括责任心、自驱力和执行力三个方面,它们应随着技术水平的提升而相应的提升。


能力越强,其责任必然越大,责任心与能力应成正比,能力再高的人,若责任心不足,企业是无法将重大的事情交给他的。责任不仅仅在于做好自己的事情,也在于敢于承担更多的挑战和职责。


平稳的度过职业生涯早期后,自驱力的重要性就更加显露无疑。被别人推动去做事与主动的高要求的做事,能力成长的差距会愈加明显。


今日事今日毕。虽然企业永远有做不完的事,但越尽早的完成一件事,才能尽早的投入另一件事。高效的执行力与强大的自驱力相得益彰。


目标与愿景


职业生涯早期看到的主要是工作愿景和个人愿景;公司愿景即在公司做更重要的事,更高的职位;个人愿景则是获得更高的薪水,享受更好的生活。


社会愿景也可以称之为行业愿景,它随着阅历的提高而逐渐展现。做开源,写博客,参与分享甚至自己创业,都会承担更多的社会责任,也会更多的获得业界认可,能更加正向的勉励自己不断向前迈进。


以社会愿景为最终目标,可以更有效的促进工作愿景以及个人愿景的达成。


最后分享一些我做开源的经验:在开源的一两年时间里,交流群和 Github 中被问到很多问题,提出很多质疑,它们推动着我在开源的路上继续前行。


在帮助别人的同时,吸取社区精华,完善自己的项目,感觉收获远多于前几年的积累。


作者:张亮

编辑:陶家龙、孙淑娟

来源:转载自数人云微信公众号


张亮,当当架构部总监,主要负责分布式中间件以及私有云平台的搭建。致力于开源,目前主导两个开源项目 elastic-job 和 sharding-jdbc。擅长以 Java 为主的分布式架构和以 Mesos 为主的云平台方向,推崇优雅代码,对如何写出具有展现力的代码有较多研究。

精彩文章推荐:

容器技术在企业落地不可不知的9个关键问题

史上最全,那些小学生都能秒懂的高大上IT术语!

架构师/CTO的内功修炼秘籍:《孙子兵法》与《九阴真经》

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存