This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
<audio id="audio" title="22 | 学习观:程序员如何定义自己的技术舒适区?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/1b/62/1b329ba43ce0bcc7001f2067f92a5562.mp3"></audio>
你好,我是臧萌。从这一节开始,我们就进入到了技术成长篇。不过在这篇里,我们不去深入聊任何具体的技术细节,而是围绕技术这个核心,和你聊聊如何看待技术,聊聊围绕技术的那些事儿。这是技术成长篇的第一篇文章,我来带你一起看看,我们应该如何定义自己的技术舒适区。
## 程序员的舒适区
平时我们谈论所处的工作状态的时候,都喜欢用舒适区、学习区、恐慌区这三个词来形容。我觉得这几个词形容得非常贴切。一个人处在舒适区,就是可以轻松愉快地应对自己工作,闭着眼睛都能把工作完成。学习区呢,就是工作有一点挑战,需要学点东西,但是也不需要费什么劲儿。恐慌区,就是看啥啥不懂,干啥啥不会,满满的压力,完全无法进行工作。
### 不要相信舒适区
其实很多职业都可以轻松打造出自己的舒适区。比如出租车司机、售货员、手机贴膜员这些职业,从技术技能角度来讲,花个几个月,就可以打造出自己的舒适区,然后就可以轻轻松松完成自己的工作了。
但是程序员这个职业不同。程序员所在的软件行业是一个高速发展的行业,如果要把技术当做安身立命的本事,那么程序员就必须要一直学习知识,才能保证自己不被淘汰。下面我来说说为什么。
假设现在你可以不太费劲地完成自己的工作紧接着的一段时间你也不需要学什么东西也可以完成自己的工作看似岁月静好十分惬意。但是设想一下在IT这么一个飞速发展的行业中为什么没有给你所做的工作带来新的挑战为什么不需要你们的技术进行升级换代
答案很可能就是你所在的公司,或者现在所从事的职业,已经处于淘汰、停滞不前的状态了。公司业务非但没有增长,可能还缩水了。这时候一切舒适、惬意、轻松所营造的岁月静好的氛围,其实都是表象。而表象下面,则是你很可能被淘汰。
### 技术要么发展,要么被淘汰
急速发展的软件行业,尤其是互联网行业,是一个不进则退的行业。业务量和业务的复杂度都在增长,留给开发的时间则是越来越短。为了满足这一切,技术的更新换代,甚至技术方向的完全改变,都是不可避免的。
比如微服务架构一个重要的目标是能解耦依赖进而加快迭代。本着配置简单、从轻从快的思想的SpringBoot很好地满足了微服务的要求让原本部署在J2EE容器里的war包变成了返璞归真的jar包可以直接运行吃过的都说香。
最近几年风行的Docker就颠覆了之前打包部署的方式让打包部署上线这个过程简单又标准。同时与之一起的虚拟化技术也颠覆了计算资源分配和管理。当然还有很多很多别的技术比如熔断降级监控等等这些技术串在一起犹如一条龙服务一样解放了我们程序员的生产力让我们可以更快地对业务需求作出响应。
如果一个程序员现在还在使用Tomcat、web.xml、打包、物理机、拷贝部署war包一方面说明公司对程序员的效率要求不高业务压力不大也就是业务发展的不好。另一方面如果这个程序员想出来找工作和面试官一聊好么考古级的技术栈请问谁愿意要这样的程序员
我们不能拿公司用不到做借口,程序员就是要有学习的本能冲动,推动公司的技术进步,至少要让公司的技术能跟得上行业标准水平。所以,就好像北上广不相信眼泪一样,我们程序员也不要相信有舒适圈的存在。如果一个工作让一个程序员享受到了舒适圈待遇,那么就说明这个工作可能要凉,可以考虑换个工作了。
### 学到手的技术会贬值
其实从利益的角度来讲,我们程序员也不应该呆在所谓的舒适区。一个客观事实是,软件行业的技术在飞速地发展,也就是说,程序员现有的技术知识存量,会一直贬值缩水。
长期来看,你觉得公司会为贬值的技术付出不变的,甚至还要增加的薪水吗?如果人才市场上,有性价比更高的人才,要的薪资更少,能做的事情更多,你觉得公司会不会考虑换人呢?
所以说,也许老的技术应对公司的业务足够了,但是这并不代表一个程序员就可以守着老的技术,在一个公司一直混下去。只要技术还在进步,那么就会有人可以用更少的工作经验,更低的薪水,更好地完成一份工作。别等到自己的看家本领被淘汰了,才想起来学习。
做一个合格程序员,就要拒绝技术舒适圈。但是拒绝舒适圈,不代表不能有一个舒适的状态。下面我们就来聊聊程序员的舒适状态。
## 程序员的舒适状态
程序员的生涯中,只有一直学习才是最舒适的状态。这里说的舒适当然不是指轻松随意,而是通过不断的学习,让自己可以轻松地应对工作,知道自己能够一直学得会、跟得上最新的技术。而自己的这种状态,可以带来发自内心的自信。这种技术自信,就是让自己舒适的根本。那要如何建立这种技术自信呢?我们接着往下讲。
### 找到提供正反馈的学习目标
其实关于学什么这个问题我也走过弯路。立过很多flag最后大都啪啪打脸。捂着“打肿”的脸我就开始反思为什么没坚持学下去呢最后我得出了一个结论学习没有形成正反馈。
没有正反馈,就是指学了之后找不到用的地方,没有看到学习带来的好处,没有感觉到自己在成长,热情就开始大大下降。最后,心里随便找个什么借口,比如工作很忙啦、这个东西用不到啦之类的,也就弃坑了。
最后,我发现我是一个比较懒的人,也发现工作确实让人“急功近利”,很难像学生时代那样心平气和地为学而学。后来,我总结出来一个寻找学习目标的法则:没事儿不找事儿,遇事儿不怕事儿。
没事儿不找事儿,就是当遇到对你没太大帮助的技术,不去投入大把精力学它。只去简单了解这个技术的大概,细枝末节不去深究,只要知道它解决的问题是什么就可以了。
这样做有两个原因,一方面,当一个技术名词频繁出现在你眼前的时候,不能完全无视它。我们得先知道它是干嘛的,通过什么方法和技巧,解决了什么问题。不到这一步,你就是固步自封了。接下来,你就得想想在自己的兴趣和工作的范围之内,这个技术能否用得上,用上了是否能带来好处。如果不能给你带来好处,那就先不去管它。
遇事儿不怕事儿,就是说每当你遇到任何需要解决的技术问题,不要绕着走,要记下来,挤时间吃透它。因为根据我的经验,你遇到过一次的问题,就会遇到第二次第三次。与其让问题一遍遍地欺负自己,不如自己主动点,第一次遇到问题的时候就别认怂,直接学起来。这样的好处就是正反馈来得很直接,成果立竿见影。
对比上一条说的“没事儿不找事儿”,如果你工作中遇到问题或者某个细节不清楚的情况,正愁不知道学啥呢,忽然一个问题“千里送人头”。这时候还等啥,送上门的不收割,难道还放走了不成?
在这里我举个自己的例子。大概在10年左右吧Hadoop在国内已经开始火了。我的心也躁动得不行大数据、分布式、Google论文这些词儿都在撩着我。于是我就立了一个flag“今年学Hadoop”。结果毛都没学只是知道了一个HDFS和Mapreduce的基本概念一丁点实操都没有。
忙吗那一年其实不算忙。就是自己懒而且内心就知道这玩意学了用不上。后来过了几年我换了工作有一个工作要用到Hadoop和HBase从把集群折腾起来了到用客户端API跑通POC总共也没用俩星期期间还做了别的很多工作。
无数的经验告诉我有需求的情况下知识的供给才是有效的供给。知识解决了问题就有了正反馈学习的飞轮才能持续地转下去。还有就是人的潜力是很大的deadline才是第一生产力哈哈。
### 有效的学习姿势
前面说的方式也有一个问题,就是可能无法系统地学习知识。如果只是东一榔头西一棒槌的学,知识会很不成系统。这样不是一个好的学习姿势。我总结出一个学习的方法,就是主动花功夫构建骨架,被动增加知识点。
主动花功夫构建骨架就是指有大的方向不会就选个趁手的资料有计划成系统的学习。任何一门新技术都要先经历这个过程。比如Spring核心就是管理对象的创建和依赖关系。你得深入了解Spring内部机制了解Spring是如何做到这一点的。
如果再往细了说,可以从以下五个点来构建骨架。
- 核心架构设计这个技术有哪些核心的架构设计。架构设计决定了技术的特征也决定了这个技术的优劣势和适用的场景。比如Java是基于字节码和虚拟机的HBase的本质就是一张排序的大表Aerospike本质就是一张大的散列表等等。
- 功能模型:这个技术有哪些功能,功能的接口是什么。
- 状态模型:系统在运行时有哪些状态,状态之间的变化原因是什么。
- 数据模型:这个技术是怎么组织数据的,是怎么处理数据的。
- 线程模型:这个技术有哪些线程,分别是做什么的。
构建这个技术骨架我大部分都是靠自己的业余时间来完成的。在我日常工作中如果统计下来算的话应该有30%到50%的时间在学习。其中很大一部分都是在学习一些细碎的小东西比如某个API或者某个library怎么用之类的。这些东西都是技术骨架上的点缀。有了自己的技术骨架接下来就可以等着问题上门了。问题送上门一个收割一个so happy。
技术骨架的重要之处还在于,它一方面可以让我们学习相关的新东西时能抓住精要、触类旁通、学得更快更准。另一方面,技术骨架可以让我们学的知识成系统成生态,这样我们才能记得更牢固,用得更顺手。
## 总结
程序员的舒适区其实就是自己的技术领地。技术领地越大舒适区越大。当你精通Java了Java就是你的舒适区。当你听到一个Java的问题心里就很舒适因为你知道这对你来说根本不是问题。
技术只有被淘汰和正在进步两种状态。即使是网络操作系统这些基础也在不断地进步。随着IPv6的普及原来IPv4的知识就被淘汰了。随着计算机硬件的发展操作系统里的CGroup也应运而生可以让我们更好地管理资源的分配。即使你原来精通网络精通操作系统如果几年不学习回过头来也会发现自己的知识已经过时了。
所以说,程序员就是要在自己的旧领地被慢慢淘汰的同时,积极地去开拓自己的新领地,让自己的舒适区不断扩大。<br>
<img src="https://static001.geekbang.org/resource/image/96/de/96d69ee22bce1293c3b9b724864dd7de.jpg" alt="">
## 思考题
这篇文章,可以说是我这个懒人关于“如何打造技术舒适区”的一套方法。你是如何学习新技术的呢?哪些技术是你领地呢?哪些技术让你觉得自己可以舒舒服服地解决相关问题呢?
欢迎你在评论区写下自己的思考,也欢迎把这篇文章分享给你的朋友或者同事,一起交流一下。

View File

@@ -0,0 +1,101 @@
<audio id="audio" title="23丨技术观做程序员技术观为何如此重要" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/c9/dc/c921f4a79d5e34ac023e95f082749fdc.mp3"></audio>
你好,我是臧萌。在这节课里,我想跟你谈谈我的技术观。
首先从技术的角度介绍一下我自己。我从业十四余年,除了担任过几个月的管理职位之外,其他时间我都是做一线的编程工作,并且以此为乐。这十四年来,我做的东西主要是偏产品、平台和框架,支撑上层业务,因此在工作中对代码和技术都是略有要求的。这些年来我也一直在学习技术,有的是出于工作需要,有的是单纯出于兴趣。
技术的重要性当然不需要强调,但是有时候物极必反,会让人迷失在技术中。这么多年来,我总结出这么两点技术观。第一,**吃透技术**。你在工作中,用到的技术必须吃透。第二,**需求至上**。技术对你来说只是满足业务和用户需求的手段。
这两个观点可谓我的肺腑之言。我喜欢做开发,学技术,但是我并不认可技术至上论,从来不认为技术可以凌驾于需求之上。我和很多人交流过,包括和我一样多年来一直从事一线编程工作的人,以及一线程序员的管理者,他们都很认同我的观点。
谈技术观,首先要和你聊聊软件工程师和技术的关系,这样你可以对这个问题有一个更深入的理解。毕竟,我们就是要和技术打交道的。
## 用技术把事情做成
程序员的大名是软件工程师,也就是说,我们是做工程的。工程就是要落地,要把一件事情做成,这是最根本的,也是软件工程师价值的体现。不管技术有多牛,只要对事情落地没帮助,那都是空气。公司为什么雇佣我们?这不在于技术本身,而在于我们可以用手中的技术,把问题搞定,让项目落地。
软件开发工程师其实和厨师一样一个是用技术写代码做软件一个是用厨艺做菜品。软件开发的技术也是一样菜刀就是Java炉灶就是数据库炒锅就是网络要做到融会贯通地使用还要不忘初心把事搞定。
简单说了一下程序员和技术的关系,下面我们再来详细说一说我技术观中的两个方面。
## 吃透技术
技术是一个程序员安身立命之本。既然是看家的本领,那就必须吃透。那么问题来了,如何吃透呢?
我自己的习惯是,把用到的主要技术,再接着深挖一层。只有深挖一层,才能让我感到安心。我自己定义的“吃透的原则”大致有三条:
1. 熟练使用:熟练使用技术解决问题,深谙技术的各种坑;
1. 精准掌控:明晰技术的能力边界,准确判断技术能否以及如何满足某个具体的业务场景;
1. 知根知底:知道技术的底层实现和关键细节,如果让自己做,可以大致做出一个来。
怎么理解这三点呢?
举个我自己的例子吧。我大学学的是Java语言大一会写Java之后我确定了两条进阶路径一手抓“写”一手抓“学”。
我当时做了一个自己的小网站做了计算器、拼图游戏、聊天程序、联机对战的俄罗斯方块等等各种杂七杂八的东西。我还熟悉了各种Java的类库和工具比如JDBCTomcat 4网络文件Java Swing/AWTAppletGraphics等等…我开始和各种乱码作斗争和各种环境与配置做斗争练就了一双高度近视但是能从万千个O中找到0的火眼金睛并乐此不疲。
在那个互联网和电脑刚刚开始普及Java在中国还是小众的时候学习资料的获取还是存在一定限制的主要靠学校图书馆。就在我学得顺风顺水的时候我遇到了这本书《深入Java虚拟机原书第二版
<img src="https://static001.geekbang.org/resource/image/2e/24/2e88fb07ee047e4c774b8c4d08894924.png" alt="">
说实话我从图书馆借来的书看不懂的有很多。什么EJB之类的我感觉跨度太大就弃坑了。但是这本书我觉得我应该要看懂这就是我要深挖的那一层——我要知道Java是怎么跑的。
那个年代学习并没有这么便捷一切只能靠自己硬啃。于是整个大二我借了还还了借一年下来反反复复地看只能算是勉勉强强看了3章。这本书有461页不包含附录有21章。这本书是我大二的痛苦回忆。
好在啃过前几章之后也可能是后面的内容简单了也可能是自己写得多了悟到了。大学毕业前我把这本书基本啃完了这才算是对Java有了一个系统的理解。
工作以后才算是踏上了吃透Java的漫漫旅程。工作之初可以说是看啥啥不懂用啥啥不会。这时候算是开荒疯狂学习各种框架、类库、工具。紧接着我工作中遇到了各种千奇百怪的问题。我的态度是能绕过就绕过先解决问题。这样的目的是能够在不背着业务压力不受时间约束的情况下有充裕的时间去找出问题原因。
程序出问题肯定有原因。我坚信这一点需要挖多深就挖多深是为了避免以后再糊糊涂涂地趟进同一个坑。不放过log里任何一个无法解释的异常不放过任何一个看不透的细节。当然这里学的有些东西并不是为了使用而是为了知其不可为而不为之或者是为了不被不知其不可为而为之的人坑是不是有点绕哈哈。
最后,我再结合这段经历做个总结,让你更直观地感受一下各个阶段的时间线以及需要做的工作。
1. 熟练使用需要做到只要面对Java 的问题,你都不觉得难。
1. 精准掌控:知道 Java 和 Java 生态的长处与短处。看到一个需求,直觉判断出可行性,难点以及可能出问题的地方。
1. 知根知底以JVM为分割线熟悉其上的类加载器、字节码、内存分配和内存模型这些 Java 生态的基石。这样做一方面是为了你能够进一步精准掌握Java。另一方面Java 作为一个设计优秀的语言,在设计自己的 DSL 的时候很多地方是值得参考的。
我面试时,如果看到有同学的简历上写着“精通某项技术”,我就会问一个标准问题:“使用这个技术的时候你有遇到过什么问题,踩过什么坑吗?”如果这个同学的回答非常干瘪,那么就说明面试者只做到了第一点,也就是熟练使用。因为如果深入地长期使用一个技术,肯定会有业务需求和技术能力边界的各种摩擦和冲突,踩过大大小小的各种坑。当然没有遇到问题自然是好的,那只能说明这个面试者很幸运。但是少了挫折,也让人距离精通这门技术,差了点火候。
## 需求至上
需求至上,是我的第二个技术观。需求一般来自于用户和业务。
我这里说的用户,不是最终用户,而是我们做的软件系统的用户。用户可能是同一个公司的不同部门,也可能是对口的业务公司。绝大多数情况下,用户非常明确地知道自己想要什么,非常明确地知道自己想要解决的问题。
那么技术到底如何支撑业务呢?
我的看法是多和用户以及业务方交流理解他们的需求才能更好地施展技术。而不能本末倒置自己想做成什么样就做成什么样。业务方不理解那是他们low用户不会用那是他们笨。如果抱着这种态度那么用再好的技术也做不成事情。
但沟通自然没那么简单。
刚开始你和业务方以及用户交流的时候,会有鸡同鸭讲的感觉,但是请相信,随着交流的深入,观点的碰撞,作为程序员的我们,会更能够理解自己所做事情的价值,也更能够选择正确的技术和解决方案。
这也是为什么很多理论派、技术流的产品,很难获得市场。但是很多实干派的产品,却可以赢得市场。技术流的产品,做出来一般都很酷,但是却把用户的需求和实际的业务问题放在了一边。而实干派,就是立足于解决用户的问题,满足业务需求,所以更容易赢得市场的认可。
举个例子为什么Google在云计算市场战不过亚马逊在我看来Google由于太过于技术流而脱离了需求。
亚马逊在2006年推出了AWS最开始的产品是IaaS、S3。当时IaaS尚属于新事物但是和传统的虚拟主机差不多IaaS的易用性和扩展性大大地方便了很多公司满足了他们对于计算和存储的需求。
Google在2008年推出了Google App Engine简称GAE。而Google这一步迈得有点大。在GAE上写程序必须用Google自己的SDK存储要用Google自己的KV数据库看起来很炫酷但是这些炫酷甚至可以称为是“划时代”的东西能赢得技术拥趸的叫好却很难赢得公司的叫座。为什么因为不实用嘛。
亚马逊胜就胜在“实用”二字。各种方便实用的功能都做到用户心坎里去了。监控报表工具怎么用怎么顺手怎么玩怎么顺心。而GAE用“华而不实”形容并不为过。回过味之后Google现在也回来好好做IaaS了但是基因难改各种边边角角的地方都能闻出华而不实的技术派味道。
还有很多小例子。比如一个公司按照自己理解的业务方向去解决自己认为有价值的问题。公司产品做了三年拿出来给用户一看用户说压根就不是他们想要的样子。比如更小的事情各种监控功能做得花里胡哨但是对于用户最关心的销量指标week by week对比却要用户开两个浏览器去人肉比。
这不是逗呢嘛?
做技术一定要懂业务,也就是要理解我们要解决的问题。你一定要懂得,怎么用技术为业务创造价值,而不是给业务添乱。
## 总结
我们除了要死磕技术之外,还要理解技术所服务的业务领域,理解用户的需求。这样,才不至于在死磕中,碰晕了头,犯想当然的错误。双管齐下,才能进一步理解自己工作的价值,朝着有价值的方向前进。
对待技术,我们不妨换个角度,不要认为自己是在学习技术,而应该这样认为:日常的工作都是在锻炼解决问题,而非技术。技术只是顺带学的。工程师的核心能力,是理解问题和解决问题的能力。
<img src="https://static001.geekbang.org/resource/image/02/70/02ce3d9ff26df0abf60a9961cd320870.jpg" alt="">
## 思考题
不知道你看完这篇文章有什么感想呢?你觉得你吃透技术了吗?对于你现在常用的技术,如果让你自己去实现,你有思路吗?你理解自己所做的系统的需求吗?
好,今天的课程就结束了,希望可以帮助到你,也希望你在下方的留言区和我参与讨论,并把文章分享给你的朋友或者同事,一起交流一下。

View File

@@ -0,0 +1,126 @@
<audio id="audio" title="24丨技术观程序员在技术的成长之路上有哪些陷阱" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/85/66/857a8200914ba0f9585f08ebc58e0166.mp3"></audio>
你好,我是臧萌。今天,我们对上一节课做一下延伸,基于上一节课中抛出来的技术观,今天我们来看一下在我们实际工作中,关于技术的事儿都有哪些陷阱。
为了给你增加一些代入感,我们首先来看一个厨师的例子。假设你是一个餐厅的老板,要招一位厨师。
厨师小白来面试了,土豆丝切得要么像吸管一样粗,要么像绣花针一样细。炒出来的土豆丝一盘偏咸,一盘偏淡,仔细一看土豆皮还没削干净。
厨师小稳来面试了只见他麻利地抓起土豆开始削皮切丝青椒去瓤切条大火爆炒。10分钟后热气腾腾香气扑鼻的土豆丝就出锅装盘了一尝标准的饭馆儿味。小稳憨厚一笑“如果有干红辣椒用油一爆那就更棒了。”
厨师小洁来面试了,对着后厨一堆菜打量了半天,眉头拧成个疙瘩,嘴上啧啧叹道:“这个土豆不行呀,大的大小的小;这辣椒也不行,得是刚刚摘下来的;油也不合适,得是古法压榨的菜籽油。”吐槽了半天,像是受了天大的委屈一样,磨磨唧唧半个小时才“勉为其难”地炒了一盘土豆丝,上口一尝,味道只能算一般。小洁皱着眉头地说道:“这些材料不大行。”
厨师小高来面试了把土豆削一削切一切一斤土豆就用半斤。土豆丝呢切得倍儿棒每根都是1mm粗6cm长误差不超过0.1mm堪称艺术品。土豆丝炒好之后小高把土豆丝一根根地码到盘子里一“根”不乱。3小时后凉透的土豆丝上桌了。
厨师老遗来面试了,进后厨第一句话就是问你:“咱这儿有土灶吗?烧柴火、拉风箱的那种,我用得惯。”你遗憾地表示,这个真没有,以后也不大可能会有。老遗叹了口气扭头走了,边走边念叨:“燃气灶烧出来的菜不香。”
现在你是老板,你会选择雇用哪个厨师呢?厨师嘛,自然要有刀工、配菜、烹饪、装盘等技术。但是最终的目的,就是要利用一切合理的资源,做出色香味均衡的菜肴给食客。
所以小稳自然是没得说。
剩下四位的毛病,相信你也已经心里有数。其实他们身上体现的问题,就是我总结的技术人常犯的四种错误:
1. 技术不扎实,不思进取;
1. 技术洁癖;
1. 一味追求新潮流,新技术;
1. 固步自封。
下面我就谈谈这四种错误该如何纠正。当然,我要强调一点,不管是哪种问题,都得充分发挥自己的主观能动性。需要你由内而外地纠正,自己认识到错误,发自内心地想改正。
## 技术不扎实,不思进取
软件行业的“小白厨师”,技术能力已经差到无法产生有效生产力的程度。
事实上,“小白”是一个相对概念,不是绝对概念。也就是说,在人生的不同阶段,我们都有可能是一个“小白”。
大学刚刚毕业的天之骄子,到公司变成一个普通员工,是小白;从之前的业务骨干,转到新的工作方向,也是小白。小白并不可怕,怕的是一直“白”下去。如果没有危机意识,惯性地以为自己可以凭借之前的地位和高度,就能够完全掌握新的工作内容,这是很危险的。
当我们换一个工作或者方向的时候,都是从小白开始,这时候的我们生产力很低,甚至为负。我们一定要意识到并且承认这一点,积极主动学习、补齐短板,至少做到合格。那么成为小稳,指日可待。
## 技术洁癖,满眼问题
软件工程师中的“小洁”满眼都是问题看到的都是各种先天不足。没错每个公司每个项目都有现实的问题。也许这个项目不能用Oracle只能使用MySQL也许这个项目不得不临时调走几个人导致团队人变少了也许这个项目不能使用Spark只能用老掉牙的Hive也许这个项目没有预算买Zing JDK……
如果只能依赖先天优势,看到不足就无从下手,那我们的工作还有什么意义?我们的价值又从何处体现?
身为软件工程师,我们拿这份工资,就是要解决这些问题的,而不是去一味地抱怨。软件工程师就是要在现有的条件下,结合自己的技术,解决问题,把事情办成,让项目落地。当然,并不是所有问题都能靠软件工程师解决,但是能解决到什么程度,就很考验一个软件工程师的功力了。
项目在落地的过程中,外部条件不如意者,十之八九。软件工程师的职责就是要找出关键点,给出合理的期待。
如果没有Oracle就找方案让数据在MySQL上也能有足够的安全性和可靠性如果临时有人被抽调走就把项目排出个轻重缓急不重要的事情先放一放如果不能用Spark就看看是否可以把数据刷新的速度从小时级变为天级如果没有Zing JDK的加持就试试把P99增加到500ms如果这个数值不理想可以后期调优。把这些数据和相关人等沟通好、协调好并得出一个可行的方案才是软件工程师的价值所在。
小稳厨师就没追求吗?他也想炒出更完美的炒土豆丝。但是他知道,有没有干辣椒,并不是炒土豆丝的必要条件。你作为老板,面对小稳圆满完成工作之后提出的请求,和小洁什么都没做就提出的一大堆请求,你会考虑满足哪个的要求呢?答案不言自明。小稳已经证明了自己,老板当然会选择给他更多信任。
张口闭口就是“这也不行,那也不行”的人,其实根子上,就是自己解决问题的能力不行。
## 避免使用不必要的技术手段
这个观点的意思其实很明确,就是当你在工作中使用一项技术,要用保守的态度,要以投入产出比做衡量,而不是根据自己对技术的偏好和冲动乱来。小高和老遗就是正反两个极端。
我们来看看这两种态度。
### 学了新技术,内心很骚动,不用不爽
首先是小高厨师,看得出来小高厨师是有点骄傲的,程序员也都是有点骄傲的。感觉我们技术人就像魔法师,看不起不会技术的“麻瓜”。而学会新技术的人,又按耐不住显摆一下的冲动。
“学了本领,不显摆显摆别人怎么知道我会呢?”于是在这种心境下,就很容易小题大做,杀鸡拿起宰牛刀。有些技术不错的年轻人,就是因为做事情的态度有问题,才导致自己发展受限。
比如说Scala这个语法糖好甜我要把项目都转成Scala的。Guava新版里这个API看着不错我用用看。
结果呢语法糖是糖衣“坑”弹各种想当然的接口和Java并不兼容Guava是Google的Google是业内典型的视兼容性为无物的公司新版Guava和老版API不兼容只能回退。当然还有更骚的比如使用库中internal的API使用实验性质的JVM功能将系统架构在一个连文档都没有的新功能上等等等等。
各种骚操作,不一而足。炫技一时爽,全组陪你加班到天亮。
其实很多时候,觉得自己一身本领无处施展,主要还是因为自己学艺不精,没学到位,不知道怎么正确地施展。下面我们就看看,怎么拯救炫技的厨师小高。
小高无疑是对技术有追求的刀工不错。但是他浪费了一半的土豆而且一道本可以10分钟就搞定的菜生生用了3个小时。小高的问题是本末倒置而且功夫没到家。
用户要的是一道炒土豆丝。速度快,味道好,这是红线,不可逾越。小高要做的,就是精进自己的技术,在保证十分钟可以搞定的前提下,再保证土豆丝一丝不乱的造型,不浪费那么多土豆。这时候,小高的这道炒土豆丝将会是饭店的一大特色。否则,就是一道摆设了。
回到我们在上文中举的例子,面对这些情况,又该怎么办呢?
Scala可以用前提是吃透能提高大家效率不增加集成工作量。Guava可以升级但是要先好好阅读文档检查兼容性问题和整个项目的依赖关系确保升级没有问题。而内部API这些真的不要主动用只有在救火的时候才可以作为临时的解决方案。
再举一个例子。我在12年的时候买了一个谷歌 Neuxs 3那时候它就支持前置摄像头面部识别解锁。但是体验是怎么样的呢10次里面大概有3次是失败的更不要提光线和角度不完美的情况。直到5年后也就是2017年苹果才推出了成熟的面部解锁方案。
所以说,一个技术的出现和一个技术可以用在生产上,完全是两个概念。一个技术在成熟之前,在确定能给用户带来价值之前,不要盲目使用。不要沉浸在自己的技术世界里不可自拔。谷歌不差钱,可以搞酷炫的东西,培养自己技术急先锋的人设,但是,普通公司并不愿意付出这个成本。
其实很多时候,老板宁愿雇佣小白,也不愿意雇佣小高。只要愿意干,技术不行可以练,不能炒菜可以先练习切菜、配菜,但如果做事情的态度出了问题,很难由外而内地改。但这一点也只能由小高自己去领悟(想让老板容忍一盘土豆丝炒了三个小时,除非厨师是老板的小舅子)。
在用宰牛刀杀鸡之前,不妨先问问自己,宰牛刀法练好了吗?
新技术要好好学,吃透了,才能用得对,用得好。用之前问问自己,使用这个技术的代价是什么?价值是什么?事情值得做吗?我是为了解决实际的需求,还是为了满足自己那颗躁动的心?
### 固步自封的遗老遗少
和小高相反老遗厨师代表的另一个极端——固步自封。用自己N年前的观点衡量现在的事物拒绝接受事物的发展对技术存有刻板偏见倚老卖老。
举个例子我有个朋友跟我吐槽说他的经理眼里只有C++看不起Java张口闭口就是Java慢Java垃圾他当初写C++怎么怎么地。听说Impala是用C++写的就找人研究要替换公司里的Hive又听说百度用C++重写了一遍Hadoop就又来了精神。可能他觉得自己有金手指吧一个手指就能搞定数据迁移客户端升级和测试。
我听到后笑得都合不拢嘴了。必须承认C++是一门优秀的技术我认识很多Java的大牛本身就是C++的大牛。技术本身没有好坏只有合适不合适。既成事实是当今整个基于JVM的大数据生态既完整又成熟稳定。而且公司在有一套Hadoop平台的前提下只有一个语言的遗老才可能因为语言原因想要去替换平台。
据说等他离职了,也没完成他的夙愿。
技术是会发展的,以前有的缺点,不代表未来一直都有。对技术不要有无谓的偏见,技术就是工具,就是用来解决问题的。一项技术能够在行业中流行,必定是有原因的。若是固步自封,早晚会被淘汰。现在还在念叨“燃气灶烧出来的菜不香”的厨师,已经不适合在饭店做厨师了,可能农家乐里还有他们的一丝生存空间。
## 总结
中国有句话,叫学好数理化,走遍天下都不怕。其实我觉得应该说成“用好数理化,走遍天下都不怕”。
软件工程师靠技术吃饭,但是世界并不是绕着技术转的。我们要对技术要有追求,但是要分清什么是自己的追求,什么是公司的追求。除了极少数脱离了低级趣味的公司之外,绝大多数公司雇佣软件工程师的目的,是为了创造价值。
技术是手段而非目的,炫技很没必要,固步自封必被淘汰。技术的目的是解决问题,而非带来更多的问题。
当然很多公司会鼓励大家学习新技术,还会举办类似“编程马拉松”的活动。这是因为技术公司基本都看到了,如果新技术用得好,很多时候可以带来生产力的提升。这么做也是变相地做人才和技术储备。公司鼓励你抬头看天,但是并不鼓励你拿着公司的钱,坐热气球去看天。
态度只能由内而外地改变。如果不是自己认识到问题,是不可能积极主动地改正的。不要让自己对技术错误的态度,成为职业生涯的绊脚石和阻力。
当然,你可能会有疑问:说得这么冠冕堂皇,自己真的能做到吗?确实人都有不自觉的时候,但是做得不对,和不认为自己做得不对,是两回事儿。我们要做的就是时常审视自己。吾日三省吾身。不怕自己犯错,只怕犯错不改。
<img src="https://static001.geekbang.org/resource/image/d8/d1/d83e88166d9945e506521a210c2d69d1.jpg" alt="">
## 思考题
最后问你几个小问题。在自己成长的路上,你有没有经历哪个阶段,是文中的小白、小稳、小洁、小高或者老遗呢?你现在对技术的态度,和这篇文章有没有冲突呢?你还见过哪些技术路上的陷阱呢?欢迎你在评论区讨论。
好,今天的课程就结束了,希望可以帮助到你,也希望你在下方的留言区和我参与讨论,并把文章分享给你的朋友或者同事,一起交流一下。

View File

@@ -0,0 +1,102 @@
<audio id="audio" title="25 | 系统架构:如何从写代码的程序员,成长为软件系统架构师?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/66/6b/66fe53769dcee9d612c6f10a7c9a7d6b.mp3"></audio>
你好,我是臧萌。这一节,我们来聊聊软件系统架构师。软件系统架构师简称架构师,它可以说是每个做技术的程序员心向往之的职位。这个职位对于很多人,还有些许神秘的味道。在这节课里,我就来和你谈谈我眼中的软件系统架构师,它其实并没有那么神秘。
## 软件系统架构师是干什么的
### 架构师的输入
软件系统架构师的工作,有两个输入。一个输入是要解决的问题,这里说的问题,可能是一个系统,可能是某一类相似的业务等,我们也可以把它认为是一个产品。另一个输入是为了解决这个问题,所能使用的资源。这里说的资源,包括系统的工期、团队和公司的技术储备。以及人才储备、业界可以使用的技术、公司的基础设施等等。
也就是说,在架构师的输入里,一手是问题,一手是资源。当然,这两个东西不是一步到位的,不会有人准备好送给架构师,而是架构师要自己去深入了解和摸索。
### 架构师解决问题的理念
随着对问题理解的深入,架构师会在脑子里慢慢形成自己对问题的理解。这时候,架构师作用中最重要的一点就会慢慢形成,那就是架构师解决问题的理念。换句话说,就是架构师如何定义这个要被解决的问题。
问题本身要尽量客观地去认识,但是如何看待和定义一个问题,就不是一个客观的事情了。这会受到每个人的理念影响。其实对一个问题的定义,很大程度上就决定了如何解决一个问题。架构师看问题的理念不同,也直接影响了应对问题的不同方案。
比如我举个例子,楼房单元大门的门锁坏了,一直叫,这是一个具体的客观的问题。但是对这个问题的认识不同,可能就应对着不同的解决方案。
如果你认为这个问题是噪音问题,那么把报警的蜂鸣器切断就解决问题了。如果你认为问题就是锁坏了,那么就去找人修好锁,就解决问题了。如果你认为问题是有人蓄意破坏,那么报警找到破坏锁的人,让他赔偿,修好门锁,并保证不再犯,就是解决问题了。
如果你认为锁经常坏是因为住户觉得开单元门的锁很麻烦并非纯粹恶意破坏那么就去给单元门升级智能锁让它支持面部识别开锁、NFC门卡开锁、密码开锁、手机App遥控一次性开锁等方便实用的功能就非常好地解决问题了。
同时你也可以在单元门口增加监控提示“锁具昂贵单元门在监控范围内破坏锁具涉嫌犯罪”。并附带一个物业电话提示物业可以帮快递人员等临时进门的人员开门帮业主新增解锁的面部ID、办理NFC门卡等事情那就更加完美地解决问题了。
架构师需要从实际问题出发,给出自己对问题的根本理解。所以,架构师和程序员相比,是一个更具有个性化的职业,也是一个更考验自己经验和技术功底的职业。而架构师最重要的能力之一呢,就是对问题的理解的深度。理解问题的这种能力,除了每个人的天赋之外,更多的是依靠你反复沟通、反复思考,以及在某个行业和领域的经验积累。
随着自己的技术积累、反复的思考演练以及过往的实际经验,架构师会慢慢形成自己的架构理念。这个理念,就会进一步形成架构师自己认识问题和理解问题的风格。当然,这些都是发生在架构师心里的事情,在外人看来,这时候架构师还没有任何实际的产出。那么,架构师的工作成果是什么呢?
### 架构师的输出
架构师工作的输出,其实有两部分。一部分是自己对问题的理解和定义,另一部分就是给出解决问题的框架模型,也就是软件架构。
#### 问题的定义
对问题的定义不是简单的文字性的描述。换句话说定义可以是从系统架构角度给出的需求分析或者说是对系统的建模。说起建模你可能会觉得比较高深不好理解。我们也可以称之为高层设计high-level design
很多中间件和产品的建模会抽象一些里面的模块也会有着架构师自己深深的特色烙印。比如Kafka将系统抽象为borker、partition、message、offset、consumer group等关键模块通过这些模块的互动组合成一个独具特色的消息系统。Kafka里面的各个模块已经非常抽象和具体的业务没有了直接的关系。
在Kafka的架构师看来消息队列和log系统是相通的。正是这种独到的、富有洞察力的见解才造就了Kafka这种独特的架构。也正是这种对问题本质的理解让Kafka很好地解决了大数据浪潮下传统消息队列无法应对的问题让Kafka在消息队列市场上独树一帜赢得了很大的市场份额。
所以说,对问题的定义很重要。能够给出直指问题要害的定义,是非常考验一个架构师,尤其是偏产品类架构师的功力的。对于很多产品来说,架构师能够给出一个准确的定义,就已经成功了一小半,哪怕这时候一行代码都没有。
#### 解决问题的模型
如果说给出问题的定义,更多的是依靠架构师对行业理解,那么给出解决问题的模型,就更多的是考验架构师的技术实力了。这时候架构师要给出的,是每个模块的详细设计。包括每个模块的接口定义、技术选型、关键实现的设计等等。
对于Kafka来说如何处理这个消息队列系统的各种技术问题就是架构师接下来要解决的问题。Kafka的理念虽然非常简约但是作为一个可靠的消息中间件Kafka本身是一个非常复杂的系统。
这就好像E=MC2一样。质能转换方程很简单但是造出一个原子弹来却是一个非常复杂的工程也和理论研究是两个维度的东西。这里我们不去展开说Kafka的架构从架构师的责任上来说构建的这个模型要能够落地到具体的模块、接口、功能。这就是系统架构师要给出的详细设计。
对于比较庞大的系统,做高层设计的架构师,可能并不是每个模块的架构师。所以架构师们也不是都在做同一层面上的事情。
如果要形容一个架构师的核心能力,那会是两个词:积累和眼界。积累来自于架构师实操过的各种产品、搜集到问题后的思考、对行业各种技术的掌控、结合实际情况在心中进行的反复演练等等。眼界是一个架构师对行业和技术的产生的自己的理解。这两者决定了一个架构师的能量。
## 如何一步步成为架构师
那么我们软件工程师,如何才能一步步地成长为软件系统架构师呢?其实在我看来,任何一个软件工程师,从写第一行代码的时候开始,就已经既是软件工程师,又是软件系统架构师了。因为我们在写代码之前,肯定要经历这么一个理解问题、分析和定义问题、构建系统的过程。知道自己要干什么,要怎么干,最后一步才是写代码。
架构师的成长之路,就是在这个路径上一步步有侧重点地走。但侧重点则正好是反过来的。
### 夯实技术实力
首先你得重视自己写代码的能力,打好学习技术的基础。在这个阶段,程序员要能写得一手好代码,把基础的知识都学牢固,比如数据结构、网络、操作系统等等,建立起自己的技术领地。在写代码中,慢慢开始理解程序设计的技巧,比如设计模式、模块化、高内聚低耦合等等。
别看前面说架构师的输入和输出部分有些虚,感觉不会技术的人也能搞。但实际情况是,一个合格的架构师,肯定是要有深厚的技术做支撑的。之所以架构师可以搞这些看上去“虚头巴脑”的东西,还能让这些东西落地,就是因为技术够硬,心里有底。
随着我们程序员经验的积累,我们会慢慢发现,写代码是整个过程中最容易的一步。这也是为什么我会在外包和外派相关的章节中说,做普通的外包和外派,如果只是给甲方写代码,那么成长是很快会看到天花板的。因为工作性质没有给这些程序员向下一个阶段发挥的机会。
### 注重架构师能力培养
紧接着,就要更进一步,开始注重自己看问题、理解问题、分析问题的能力。简单来说,就是把重心向前挪,理解代码背后解决的问题,理解代码背后的设计理念,主动思考这些“虚头巴脑”的问题。
这个阶段,可以从熟悉自己做的系统的架构设计开始。也可以找一些优秀的开源框架,学习它们的架构设计。比如 Java 中最常见的slf4j就是一套设计得非常优秀的日志系统。几乎每个 Java 程序员都在用但是我们去深入理解过它的架构吗在slf4j的世界里它是如何定义“记日志”这个事情的它又是使用了哪些技巧让这个日志框架可以灵活高效呢
同时,这个阶段程序员也要开始主动承担起,一些小模块的设计工作。系统架构师是一个需要非常多的实践积累的工作。每个人都有自己的成长方式,但是多做设计多思考,是普通人进阶软件系统架构师的不二法门。
### 保持开放的心态
软件系统架构师要有一个开放的心态不能固守己见。优秀的系统架构需要跟上发展打破常规。比如前面提到的Kafka的设计我当时第一次看到的时候不由得心里说我靠这玩意有意思对味儿。
再举个简单的例子。Chrome在飞速抢占市场份额的那几年曾经有一个大的变化那就是让每个页面都是一个进程。要知道之前多标签的浏览器都是共享一个进程的。我当时得知这个变化看着我的破电脑心里想Chrome这是脑子进水了么
现在回过头来想我这种用着破电脑的小程序员和Chrome的架构师的境界果然就是不一样啊。每个页面一个进程一方面解放了JS engine让不同的标签之间不再受制于同一个JS engine。另一方面这种变化也代表了浏览器发展的未来方向因为一个标签它就是一个单独的应用程序啊。这是Chrome对标签的崭新定义只是我等俗人要过很多年才能体会到的。
我们在实践系统架构的时候,也不要怕推翻自己之前的设计。你应该这么想:如果对于一件事情,我今天的认识和昨天是一样的,那就代表我这一天没有成长,如果我今天的认识和去年是一样的,那就代表我这一年没有成长。你想想,是不是这个道理?
## 总结
软件架构师,是要从无到有去设计出一个“新的世界”,制定这个世界的各种规则,让业务在自己设计的这个世界里运转起来。而这一切都需要实际经验的积累,这种积累需要的条件,远比单纯的技术积累复杂,所以架构师是一个需要岁月沉淀的工作。
对于程序员来说,不是年纪大了没人要,而是能力没跟上年纪的增长,才会没人要。程序员做架构,不需要有架构师这么一个名头。因为如果我们自己做一些业余项目,肯定就是先开始思考架构设计。如果是工作中安排的编码工作,其实只要自己平时写代码的时候多思考,多想想代码背后的业务,代码背后的系统设计,慢慢也会积累一些系统架构相关的经验。
当然,更重要的是去实践。工作中没机会,可以自己搞一些业余项目实践。自己想的可能很好,真的实际去做做看,可能会发现自己想的东西有很多纰漏。而系统架构的经验,就是这样一点点积累起来的。<br>
<img src="https://static001.geekbang.org/resource/image/b7/fb/b7be1ec0fa8e031c0d01eaeeab05ecfb.png" alt="">
## 思考题
关于软件架构师这个职位你有哪些疑问呢?你在工作中有承担过软件架构师的职责吗?你遇到过哪些优秀的软件架构师呢?
好,今天的课程就结束了,希望可以帮助到你,也希望你在下方的留言区和我参与讨论,并把文章分享给你的朋友或者同事,一起交流一下。

View File

@@ -0,0 +1,85 @@
<audio id="audio" title="26 | 系统集成:为什么最容易出问题的是系统集成?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/f2/3f/f22c82ef5a8da0880695259bda2e913f.mp3"></audio>
你好,我是臧萌。在上一节中我们聊了软件系统架构师。软件架构师完成了最核心的系统,但是这还远远没完。如果你想让这个系统真的运转起来,那还需要系统集成。而且在我看来,系统集成很多时候所占的时间和精力,远比系统核心要多。
那到底什么是系统集成呢?系统集成,简单来说,就是要对接、落地,验证,看到真正的成果。
## 吃上一道新菜,过程远比你想的复杂
我们拿饭店来打个比方。假设我们现在运营着一个连锁饭店,中心厨房会为每个连锁饭店配送半成品的菜品。现在我们要推出一款叫“三菌笋片烩鸡丁”的新菜品。对于新菜品来说,一开始我们要先构思,然后去小范围地验证这个菜品。如果在这个小范围内得到一致好评,那第一步就算完事了。
这时候,如果用软件系统研发的进度做对比的话,菜品研发部分,就是完成了系统架构和关键模块的编写,也就是完成了核心系统的开发。请大家试吃就是搞出一个演示给大家看,结果就是大家看着核心系统的演示,都觉得功能很棒,翘首期待能早日用上。
这是决定这个系统特色的一步,也是最有创造性的一步。但得到了大家的认可,这能算成功了吗?远远没有。这只能算是迈出了通向成功的第一步,距离成功,还差着系统集成这关键的一步呢。
回到我们的例子。我们的目的是为连锁饭店推出一道新的菜品。我们需要给连锁饭店的食客们安全快速地呈上这道新菜,才能算成功。而一个菜能在厨房做出来,和一个菜能一年能在所有饭店长期保持稳定水准,是完全两个概念,难度也是两个级别。
三菌笋片烩鸡丁这道菜,用到了三种菌菇以及笋片和鸡丁。三种菌菇可能无法保证每一个连锁店所在地都有货,可能某些菌菇即使有货,价格也波动很大,可能有的菌菇对保鲜和运输的要求比较高,弄不好就容易变质,造成食品安全问题。
饭店一旦要连锁,类似的问题就会不断地暴露出来,并且不断放大。如果类似问题处理不好,那么这个菜品就是失败的。而这个让新菜品落地的过程,类比到软件系统里,就是系统集成。
## 如何不掉进软件系统集成那些坑
那我们继续回到软件系统。软件系统在特定的场景,无其他干扰因素的理想情况下正常工作,并不代表它就可以用了。外界的很多因素,都有可能影响系统发挥出本身的功能。系统集成的过程,才是对系统的大考。
每个系统面对的情况都不一样,这里我还是用一个电商网站来举例子,给大家聊聊软件系统集成中常见的那些坑、如何尽量避免掉进坑里、以及要是你不小心掉进去的话,如何快速而优雅地爬出来。
电商网站有库存、商品展示、订单管理、退换货等等子系统。退换货子系统需要对接供货商的ERP系统。
### 系统内部集成:架构统一
所谓系统内部的集成,就是一个系统各个模块之间的集成。比如将库存记录、进出库存、库存盘点等模块等,集成为一个完整的库存系统。如果一个系统设计得过关,那么对于这种集成来说,出问题的几率还是比较小的,而且即使有问题,也容易解决。原因在于这个系统本身就是新的,是遵循着一个统一的架构设计做出来的。各个模块之间在设计之初,就已经做好了集成的准备。
这时候出现的问题,大多是因为一些实现的细节,或者是设计时没有描述清楚造成的。比如代码接口定义不统一,数据交互的格式不统一等等。我之所以说这时候还比较容易解决,就是因为新系统没有历史负担,不需要考虑兼容性等问题,所以只要大家将之前的误解消除,解决问题的工作量还是可以估算的。
这时候如果出现比较大的问题,很可能是因为模块由不同的架构师来负责,而不同的架构师之间没有充分的沟通。好的方式,应该是让一个架构师负责一个完整的模块,根据开闭原则,提供统一且简单清晰的接口,对外提供功能。
正所谓,令出多门,兵家大忌。如果很多人都可以拍板做决定,那么事情到头来很可能会乱套。即使需要不同的架构师负责,也要有一个总的架构师,提供统一的总体架构,解决架构师之间的争论。
好的这时候我们有了一个库存模块功能都测试过了而且它接口简单精炼一张A4纸就能打印出来。别的模块也纷纷告捷大家满心欢喜地开始向前推进。
### 外部系统集成:不做假设
这时候退换货模块需要就退货功能跟外部ERP系统集成了。当你自信满满地问你们的退货接口是什么发给我看看。对方发给你一个文档描述了退货需要提供的数据。你看完发现需要的数据没啥特殊的一切尽在掌握。
于是你按照要求对接的代码就写了起来没两天就弄好了和对方说你们的RESTful接口给我测试一下我这边的数据弄好了。对方一脸问号地说我们没有什么RESTful接口你把数据保存成那个格式上传到我们这个FTP就行我们三天内处理完然后你再去那个FTP上下载一个叫yyyy-mm-dd-result.json的文件就可以了很简单的。
这时候你终于知道了什么叫做两个世界的人在你眼里对方重新定义了简单。同时你也体会到了什么叫做失控。按照之前的设计退换货是需要即时给出结果的。这种通过FTP传递数据需要三天处理的模式完全打破了之前的设计。且不说很多内部的功能都要重新设计重新做对外的接口也要大改而且还会影响所有已经和退换货模块集成好的模块。
和外部系统集成,越早确定细节越好,不要假设任何东西。任何在你看来很自然的东西,可能对方就是没有。你的系统如果对这些想当然的东西有强依赖,那么代价可能是惨重的。
这里我可以再举一个例子。如果你的系统的核心功能依赖于某个外部系统的功能比如某个数据库功能那你就先把这个通路确定好。比如公司购买的数据库是否有这个功能、公司的DBA是否允许我们使用这个功能、这个功能的吞吐量有多大等等。
如果在集成的时候发现,你的系统核心功能与外部系统依赖之间存在问题,这会变得非常麻烦。因为外部系统已经存在,外部系统能不能因为你的需要来做出改变,是非常不确定的。而不同的系统之间,本来就没有统一的架构,系统之间的集成点,需要在设计之初反反复复确认并验证。
### 漫漫集成路之问
下面我们来谈谈系统集成中其它常见问题。
首先就是配置。有些模块的配置非常繁琐甚至配置比代码都麻烦。有些系统的配置需要经验的积累和专业的学习比如KafkaHBaseHystrix等中间件系统。和这些模块或系统集成代码之外的配置将是一个非常容易出问题的点比如说配置不合理、配置被覆盖、配置非法导致没有生效等等。
如何应对这类集成呢我的建议是眼见为实。在你用到配置的地方将配置用log的形式输出出来方便用二分法确定问题。
接着是数据。其实系统集成的时候,很大一部分问题是和数据相关的。这里我给出两类常见的数据问题,一个是用户输入的数据,一个是数据交换。
对于用户输入的数据简单来说一个字节都不要相信。用户可以给用户名填写100k个字符、用户填写的日期可能是未来或者几百年前、用户可能输入任何数据。所以在使用用户的数据之前要把数据全部检查一遍。还是那句话不要做任何假设哪怕前端已经做了数据验证自己的系统也要保护性地验证一下数据。
至于数据交换也是一个非常容易出问题的点。系统集成少不了数据交换因为大家对数据schema定义的不同数据交换往往伴随着数据格式的转换等操作。这时候不同系统对于数据缺失、默认值、数据约束等规定的不同可能会造成各种问题甚至出错。数据在不同系统之间交换还可能伴随着数据丢失等问题。
所以外部系统给的数据一个字节也不要相信。当和外部系统进行数据交换的时候一定要在系统交互的边界好好记log。要能够将数据的输入、转换、出错等各种情况都记录详细的log方便排查问题。
## 总结
系统集成为什么这么麻烦,这么漫长,原因在于一方面,它需要给出最终的被大家认可的成果。另一方面,在现实条件中可能有各种各样,之前没有想到的问题。这些问题,都会在系统集成的时候,一一暴露出来,成为系统集成路上的拦路虎,造成无法交付成果的情况。
每当我听到有同学说我代码写完了这个事情可以结束了。我都会露出尴尬而不失礼貌的微笑。我不能否定这个结论因为如果你问我还有什么事情没弄完我也可能说不出个123来。但是我敢肯定这位同学可能还要付出一倍甚至数倍写代码的时间才能让这个代码真的跑起来才能说这个事情结束了。
这个过程,就是系统集成,是我们在为自己的想当然、对需求的理解偏差、经验的欠缺、能力的不足、视野的限制、不充足的前期调研、未预料到的意外来付出的代价。功力深厚的架构师,也是一个系统集成的大师。他可以在设计阶段,根据自己的经验,尽量减少问题,降低难度。所以,能够越少地付出这个代价,越能代表自身综合能力的提升,也是代表自身价值的提升。
<img src="https://static001.geekbang.org/resource/image/b9/12/b92f2c8698d34448bf31171194fd4f12.jpg" alt="">
## 思考题
系统集成,是任何一个系统都逃不过的大考。你有过哪些关于系统集成刻骨铭心的经历呢?关于系统集成,你遇到过哪些问题,又有哪些实践经验可以分享呢?
好,今天的课程就结束了,希望可以帮助到你,也希望你在下方的留言区和我参与讨论,并把文章分享给你的朋友或者同事,一起交流一下。

View File

@@ -0,0 +1,87 @@
<audio id="audio" title="27 | 答疑篇:什么样的技术观能够更快成长?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/74/46/741e26c1c8bb9cf0b9fcbcd665f09546.mp3"></audio>
你好,我是臧萌。转眼之间,咱第四个模块也结束了。在这个模块里,我们围绕着技术,聊了聊程序员的技术领地、我们程序员应该如何看待技术、如何从主要做开发的程序员成长为软件架构师、以及如何不掉进软件系统集成的那些坑。
在一开始,我们只要关心技术就可以了,打好技术基础,养成学习技术的习惯。紧接着,我们要开始审视自己看待技术的观点,也就是技术观。因为随着我们程序员的成长,工作的重心将开始从单纯的技术,转向如何用技术服务业务。
在这个过程中,如果你打算继续走技术路线,很大的一种可能就是工作重心继续上移,在自己思考技术服务业务的过程中,逐渐培养自己做软件架构的能力,进而成为一名软件系统架构师。
## 软件架构师需要哪些能力?
软件系统架构师,要有自己的经验积累和独到的眼光,要能够很好地认识问题、对问题建模、解决问题。除此之外,还要考虑的一点就是软件系统的集成。因为软件系统的集成,才是对一个软件系统的终极大考,也是对架构师综合能力的大考。一个软件架构看上去很美的系统,如果不能很好地落地集成,最后的结果只会是叫好不叫座,被束之高阁。
你如果能够走通这些关键节点,在我看来就已经是一个软件研发的全能人才了。软件研发全能人才更多地是从个人综合能力上来讲,而我们平时说的全栈工程师,更多地是从技术层面来谈。技术是武器,使用哪种武器解决问题,肯定会影响最终的架构。不过在架构之上,理解问题、分析问题、解决问题的能力,这个和具体的技术是没有太大关系的。
所以,我更愿意建议程序员,不要把自己的视野局限在技术层面,而是要把视野扩展到从看到问题,到最终解决问题这么一个全过程。这也是整个技术成长篇里,我想表达的一个非常重要的观点。
必须补充一点的是,并不是说做了软件系统架构师,就不需要持续学习技术了。软件系统架构师也必须持续不断地更新自己的技术库,维持甚至扩张自己的技术领地。这样才能够让自己做出适合当下甚至未来发展的架构,可以进一步可以减少系统集成的风险。技术是武器,熟悉武器的发展,指挥起打仗来心里才能有底气,才能灵活应对。
这部分里,很多同学提出了非常多有价值的问题,也有同学分享了自己的心得体会,这里我们一起来看一下。
## 修炼内功,厚积薄发
关于技术舒适区,**@牛牛** 同学分享了自己的感受。开始的时候,学习很痛苦,等熬过这段时间,就会有各种小惊喜,持续不断地形成正反馈、就越来越有学习的动力了。小惊喜来自于随着知识的融会贯通,之前不懂的事情,一下就懂了。
的确是这样的,尤其是数据结构、 算法、操作系统、网络、计算机系统结构这些内功,虽然没有立竿见影的效果,但是会对你还没学的东西都有加成。你会发现内功一旦深厚了,学习其他东西会很快。
举个简单的例子HBase里用一个叫做Bloom Filter的数据结构去做过滤Bloom Filter的特点是如果这个值存在Bloom Filter绝对会返回true但是如果某个值不存在Bloom Filter可能会返回true也可以返回false。它里面用了一种非常精妙的设计可以在可控的内存占用下达到预期的判定准确率。如果不事先学习肯定会让自己学起来阻力重重。但是如果之前就学会了那看到的时候就只需会心一笑。
学好基础,以后学习就一帆风顺。基础不行,学习就是步步维艰。
## 搭建骨架,稳步前进
**@pyhhou** 同学对如何构建自己的技术骨架比较感兴趣。我觉得这是一个很好的问题。确实技术骨架不是一开始就能搞起来的,尤其是在自己的知识存量还没有形成规模效应,可以让我们触类旁通的时候。
我从开荒的状态说起吧以Spring为例子。我们首先肯定是要学好Java明白对象、类、方法、多态、继承等核心概念。对于Spring来说慢慢还要知道注解、反射、代理这些Spring会重点用到的知识。
然后就是学Spring和学一般的技术一样你需要找个趁手的书或者资料一以贯之地啃完。可以是我们的课程也可以是官方文档。这个过程开始更多的是比着葫芦画瓢先看效果。
接着,你就可以发挥自己的想象力来探索了。这时候的最好的方式就是多写程序,想到什么就拿出来写写、练练,验证自己的想法。这一步,就是在慢慢构建你自己的技术骨架了。
所谓骨架就是藏在表面之下的东西虽然看不到但是如果没有它们支撑的话表面的东西就不牢固。就拿Spring来说你要能知道这些bean是如何被描述、被创建、被组装的。做到这些之后当出了某种异常你就很容易能找出是哪个步骤的问题马上去修正。
如果能做到这些让你自己写一个IoC的框架也不是难事。当然并不是说一定要做的像Spring这么全面可能只是一个微小的内核但是相信我如果你自己做一遍、思考一遍你会对Spring的认识更近一层。当你把自己的设计和实现与Spring做对比时会记得更牢固印象更深刻。这个步骤可以帮助你完整地构建关于这个技术的骨架。
当然,也不是说每个东西都要自己照着写一遍。即使不去自己做一遍,也要有意识地在脑子里思考一下,如果是你自己做,你会如何设计、如何架构、遇到想不通的地方去仔细看看现有的设计,能够有很多收获。
**@Sdylan** 同学也分享了自己构架技术骨架的方式。虽然方式不同,但和我的划分也有异曲同工之妙。
其实每种技术都有侧重性,有些技术可能也需要这几种模型之外的模型。比如偏向数据存储和处理的技术,重点考虑它的架构,然后是数据模型和线程模型。把这几个搞清楚了,就知道这个玩意是怎么转的,出了问题可能是哪里的问题,也能知道它是否适合一个场景。
其实每个人都有自己的习惯,重要的是要有个技术骨架,这样才能把知识整合在一起,才能系统地学会新领域的知识。否则就容易什么东西都只会个表面,容易浮躁。
## 服务业务,不忘初心
在技术观部分Sdylan 同学提到,空谈技术,不顾业务,只会误了技术误了业务。技术本来就是为了解决问题而生的,若脱离了问题。就会变得毫无价值,生命周期也是短的。只有落地,随着业务发展才能长久。对个人而言,用到必须里外吃透,做的需求至少要理解到为啥做需求,解决什么业务痛点。
关于生命周期,可以分享一个我的看法。其实做技术久了会发现,技术过几年大概率会扔掉,而业务反而不容易扔掉,积累起来越来越值钱。
其实我们程序员容易忽视业务,或者说容易钻到技术里出不来,也是有客观原因的。就是做技术需要全心全意的投入,就是需要你钻进去。这时候,就容易忽略我们的初心:服务业务。所以我们程序员可以时不时地,从技术的世界里钻出来,重新想想业务是什么,我们钻的深度和方向,是否还是为了业务服务。
## 从业务来,到业务去
在系统架构部分有同学表示好的架构都是从业务问题来的然后再抽象出来。一个很好的例子就是Kafka。看完此文章后也开始慢慢理解公司设计出来的内部架构以前觉得这玩意不就是Spring系列值得这么整么。其实发现是自己对业务的理解过于狭窄随着接触的业务多了开始慢慢明白为啥这么做。总之架构师首先是业务架构师本质上是业务与架构的tradeoff关键是对问题思考和抽象程度。
这个总结很到位。所以你也理解为什么软件工程师有饭吃吧。同样是造轮子,在我看来,软件工程师不是为了重复造轮子,因为对于每辆飞速行驶的车来说,轮子上各种细节的雕琢,都可能会对业务带来巨大的提升。
这辆业务的车是在沙漠里开,还是在湿路上开,还是在山路上开,都会对轮子提出非常具体的要求。甚至沙子是细沙还是粗沙,都不一样。所以只要全世界的业务还都没挪到软件系统上,只要业务还在发展,软件工程师就一直有饭吃。
当然,重新造轮子,得到最大锻炼的就是架构师。架构师要珍惜珍惜再珍惜每一个重新造轮子的过程,深入理解公司业务的需求,构建业务模型,打造能帮助公司飞驰的轮子。解决实际的问题,是锻炼的绝佳机会。这种公司花钱出人让人得到实践锻炼的机会,遇到了做梦都能笑醒。
## 保持数据警醒度
关于系统集成,很多同学都提到了 / 打印外部系统传来的参数。这个确实是一个很重要的点。确实系统集成的很大一部分就是数据。比如接入别人的数据,读取别人写的数据库,把数据传给别人等等。
为什么数据这么容易出问题呢?因为数据交互就涉及到数据的序列化和反序列化,数据的封装和传输。其中任何一个环节都可能造成数据的错误或丢失。
比如说最常见的http协议。http header虽然可以放一些数据但是它是有长度限制的。而且不同的服务器对这个长度限制的默认设置也不一样。所以在系统集成时任何外部的数据都不要信同时发给外部的数据自己也记录一下。
## 总结
在这一篇里,我们聊了技术和架构,核心是程序员的成长。虽然没有涉及到具体的技术知识,但跳出纯技术的角度来看程序员这份工作,知道我们为何学技术、知道如何用技术、思考如何用技术给自己的职业生涯助力,也是非常重要的事情。
这一篇的内容,是按照由浅入深来安排的。侧重点分别是为何要持续学习技术,如何看待技术和工作,如何培养自己架构师的能力,以及如何培养自己将系统落地的能力。你可以参考自己当前的状态,思考之前是否有不足,也希望能对你日后的职业发展有所帮助。
以上就是答疑篇的内容,不知道有没有解决你的困惑呢?
欢迎你在评论区与我交流一下你的想法,也欢迎把这篇文章分享给你的朋友或者你的同事,一起来交流一下。