> 2021年12月25日信息消化 ### 21 Lessons Learned in 2021 origin: [21 Lessons Learned in 2021](https://sahilbloom.substack.com/p/21-lessons-learned-in-2021) > Abstraction & synthesis of the most transformative year of my life #### Engineered Serendipity I believe that some of what we call "luck" is actually the macro result of 1,000s of micro actions. Your daily habits can put you in a position where "luck" is more likely to strike. Increase your serendipity surface area. Engineer your own serendipity. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F53f4ae55-5599-4a1b-b62d-b9b847e20c28_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F53f4ae55-5599-4a1b-b62d-b9b847e20c28_1600x900.png) #### The Exponential Growth Challenge Human brains cannot fathom the insane power of exponential growth. We consistently underestimate its impact. When you're on an exponential growth curve—stop trying to set specific goals. Strap in, keep your head back, and enjoy the ride. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a65736-8e3d-42a9-ace4-49afafec089c_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a65736-8e3d-42a9-ace4-49afafec089c_1600x900.png) #### Work Like a Lion Most people are not wired to work 9-5. Modern work culture is a remnant of the Industrial Age—long periods of steady, monotonous work. If your goal is to do inspired, creative work, you have to work like a lion. Sprint when inspired. Rest. Repeat. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc26d416-963d-44ac-ae13-b4f7a44cf3fc_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc26d416-963d-44ac-ae13-b4f7a44cf3fc_1600x900.png) #### Overestimate a Day, Underestimate a Year We overestimate what we can accomplish in a day, and underestimate what we can accomplish in a year. To fight this, focus on small daily actions that compound over the long-term. Small things become big things. When in doubt, zoom out. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5eedbff-a175-40e8-a536-2c759ba0cb6e_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5eedbff-a175-40e8-a536-2c759ba0cb6e_1600x900.png) #### Step into the Arena It's easy to stand on the sidelines. It's hard to step into the arena. It's scary to put yourself out there, to expose yourself, to become vulnerable. But it makes all the difference. Get off the sidelines. Be the Man—or Woman!—in the Arena. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8105865-e40d-4480-ad9f-a1589af9e301_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8105865-e40d-4480-ad9f-a1589af9e301_1600x900.png) #### Pay It Forward No matter how far you go, always remember that you didn’t make it on your own. Pay it forward. Be a mentor. Be a champion for others. Their growth should become a source of tremendous joy and pride. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ff8aff-e7d5-4078-8b23-6aec0a3a886d_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ff8aff-e7d5-4078-8b23-6aec0a3a886d_1600x900.png) #### Operate in Your Zone of Genius Your Zone of Genius is where your interests, passions and skills align. Find yours, then slowly shift your life to spend more time in it. Start playing games you are uniquely well-suited to win. You'll find more happiness, fulfillment, and success. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F3b654d45-585c-45ae-834f-a000407bf103_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F3b654d45-585c-45ae-834f-a000407bf103_1600x900.png) #### Build New Circles The internet has made it possible to connect with people all around the world instantaneously. Use it to your advantage. Build new circles—positive sum, decentralized friend groups are force multipliers for your growth. When one person wins, we all win. [![img](https://cdn.substack.com/image/fetch/w_1100,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbf597c1-8224-48a5-8d3b-5fe5ea137427_1600x900.png)](https://cdn.substack.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbf597c1-8224-48a5-8d3b-5fe5ea137427_1600x900.png) ### 我做系统架构的一些原则 > MEMO > > 回归解决问题的本质。 origin: [我做系统架构的一些原则](https://coolshell.cn/articles/21672.html) #### 关注于真正的收益而不是技术本身 - **是否可以降低技术门槛加快整个团队的开发流程**。能够加快整个团队的工程流程,快速发布,是软件工程一直在解决的问题,所以,系统架构需要能够进行并行开发,并行上线和并行运维,而不会让某个团队成为瓶颈点。(注:就算拖累团队的原因是组织构架,也不妨碍我们做出并行的系统架构设计) - **是否可以让整个系统可以运行的更稳定**。要让整个系统可以运行的更为的稳定,提升整个系统的 SLA,就需要对有计划和无计划的停机做相应的解决方案(参看《[关于高可用的架构](https://coolshell.cn/articles/17459.html)》) - **是否可以通过简化和自动化降低成本**。最高优化的成本是人力成本,人的成本除了慢和贵,还有经常不断的 human error。如果不能降低人力成本,反而需要更多的人,那么这个架构设计一定是失败的。除此之外,是时间成本,资金成本。 #### 以应用服务和 API 为视角,而不是以资源和技术为视角 国内很多公司都会有很多分工,基本上都会分成运维和开发,运维又会分成基础运维和应用运维,开发则会分成基础核心开发和业务开发。不同的分工会导致完全不同的视角和出发点。比如,基础运维和开发的同学更多的只是关注资源的利用率和性能,而应用运维和业务开发则更多关注的是应用和服务上的东西。这两者本来相关无事,但是因为分布式架构的演进,导致有一些系统已经说不清楚是基础层的还是应用层的了,比如像服务治理上的东西,里面即有底层基础技术,也需要业务的同学来配合,包括 k8s 也样,里面即有底层的如网络这样的技术,也有需要业务配合的 readniess和 liveness 这样的健康检查,以及业务应用需要 configMap 等等 …… **这些东西都让我感觉到所谓 DevOps,其实就是因为很多技术和组件已经分不清是 Dev 还是 Ops 的了,所以,需要合并 Dev和 Ops**。而且,整个组织和架构的优化,已经不能通过调优单一分工或是单一组件能够有很大提升的了。其需要有一种自顶向下的,整体规划,统一设计的方式,才能做到整体的提升(可以试想一下城市交通的优化,当城市规模到一定程度的时候,整体的性能你是无法通过优化几条路或是几条街区来完成的,你需要对整个城市做整体的功能体的规划才可能达到整体效率的提升)。而为了做到整体的提升,需要所有的人都要有一个统一的视角和目标,这几年来,我觉得这个目标就是——**要站在服务和 对外API的视角来看问题,而不是技术和底层的角度。** #### 选择最主流和成熟的技术 技术选型是一件很重要的事,技术一旦选错,那会导致整个架构需要做调整,而对架构的调整重来都不是一件简单的事,我在过去几年内,当系统越来越复杂的时候,用户把他们的 PHP,Python, .NET,或 Node.js 的架构完全都迁移到 Java + Go 的架构上来的案例不断的发生。这个过程还是非常痛苦的,但是你没有办法,当你的系统越来越复杂,越来越大时,你就再也不能在一些玩具技术上玩了,你需要的更为工业化的技术。 - **尽可能的使用更为成熟更为工业化的技术栈,而不是自己熟悉的技术栈**。所谓工业化的技术栈,你可以看看大多数公司使用的技术栈,比如:互联网,金融,电信……等等 ,大公司会有更多的技术投入,也需要更大规模的生产,所以,他们使用的技术通常来说都是比较工业化的。在技术选型上,千万不要被——“你看某个公司也在用这个技术”,或是一些在论坛上看到的一些程序员吐槽技术的观点(没有任何的数据,只有自己的喜好)来决定自己的技术,还是看看主流大多数公司实际在用的技术栈,会更靠谱一些。 - **选择全球流行的技术,而不是中国流行的技术**。技术这个东西一定是一个全球化的东西,不是一个局域化的事。所以,一定要选国际化的会更好。另外,千万不要被某些公司的“特别案例”骗过去了,那怕这个案例很性感,关键还是要看解决问题的思路和采用的技术是否具有普世性。只有普世性的技术有更强的生命力。 - **尽可能的使用红利大的主流技术,而不要自己发明轮子,更不要魔改**。我见过好些个公司魔改开源软件,比如有个公司同魔改mesos,最后改着改着发现自己发明另一个 kubernetes。我还见过很多公司或技术团队喜欢自己发明自己的专用轮子,最后都会被主流开源软件所取代。完全没有必要。不重新发明轮子,不魔改,不是因为自己技术不能,而是因为,这个世界早已不是自己干所有事的年代了,这个时代是要想尽方法跟整个产业,整个技术社区融合和合作,这样才会有最大的收益。那些试图因为某个特例需要自成一套的玩法,短期没问题,但长期来说,我都不看好。 - **绝大多数情况下,如无非常特殊要求,选 Java基本是不会错的**。一方面,这是因为 Java 的业务开发的生产力是非常好的,而且有 Spring 框架保障,代码很难写烂,另外,Java 的社区太成熟了,你需要的各种架构和技术都可以很容易获得,技术红利实在是太大。这种运行在JVM上的语言有太多太多的好处了。在 Java 的技术栈上,你的架构风险和架构的成本(无论是人力成本,时间成本和资金成本)从长期来说都是最优的 在我见过的公司中,好些公司的架构都被技术负责人个人的喜好、擅长和个人经验给绑架了,完全不是从一个客观的角度来进行技术选型。其实,从 0 到 1 的阶段,你用什么样的技术都行,如果你做一个简单的应用,没有事务处理没有复杂的交易流程,比如一些论坛、社交之类的应用,你用任何语言都行。但是如果有一天你的系统变复杂了,需要处理交易了,量也上来了,从 1 到 10,甚至从 10 到 100,你的开发团队也变大了,需要构建的系统越来越大,你可能会发现你只有一个选择,就是 Java。想想京东从.NET 到 Java,淘宝从 PHP 到 Java…… 注,一些有主观喜好的人一定会对我上述对 Java 的描述感到不适,我还用一些证据说明一下——全中国所有的电商平台,几百家银行,三大电信运营商,所有的保险公司,劵商的系统,医院里的系统,电子政府系统,等等,基本都是用 Java 开发的,包括 AWS 的主流语言也是 Java,阿里云一开始用 C++/Python 写控制系统,后面也开始用 Java ……你可能会说 B站是用 go语言,但是你可能不知道 B 站的电商和大数据是用 Java……懂着数据分析的同学,建议上各大招聘网站上搜一下 Java 的职位数量,你就知道某个技术是否主流和热门…… #### 完备性会比性能更重要 我发现好些公司的架构师做架构的时候,首要考虑的是架构的性能是否能够撑得住多大多大的流量,而不是考虑系统的完备性和扩展性。所以,我已经多次见过这样的案例了,一开始直接使用 MongoDB 这样的非关系型数据库,或是把数据直接放在 Redis 里,而直接放弃关系型数据库的数据完备性的模型,而在后来需要在数据上进行关系查询的时候,发现 NoSQL 的数据库在 Join 上都表现的太差,然后就开始各种飞线,为了不做 Join 就开始冗余数据,然而自己又维护不好冗余数据后带来的数据一致性的问题,导致数据上的各种错乱丢失。 所以,我给如下的一些如下的架构原则: - **使用最科学严谨的技术模型为主,并以不严谨的模型作为补充**。对于上面那个案例来说,就是——永远使用完备支持 ACID 的关系型数据库,然后用 NoSQL 作补充,而不是完全放弃关系型数据库。这里的原则就是所谓的“先紧后松”,一开始紧了,你可以慢慢松,但是开始松了,以后你想紧再也紧不过来了。 - **性能上的东西,总是有很多解的**。我这么多年的经历告诉我,性能上的事,总是有解的,手段也是最多的,这个比起架构的完备性和扩展性来说真的不必太过担心。 为了追求所谓的性能,把整个系统的完备性丢失掉,相当地得不偿失 #### 制定并遵循服从标准、规范和最佳实践 这个原则是非常重要的,因为只有服从了标准,你的架构才能够有更好的扩展性。比如:我经常性的见到很多公司的系统既没有服从业界标准,也没有形成自己公司的标准,感觉就像一群乌合之众一样。最典型的例子就是 HTTP 调用的状态返回码。业内给你的标准是 200表示成功,3xx 跳转,4xx 表示调用端出错,5xx 表示服务端出错,我实在是不明白为什么无论成功和失败大家都喜欢返回 200,然后在 body 里指出是否error(前两年我在微信公众号里看到一个有一定名气的互联网老兵推荐使用无论正确还是出错都返回 200 的做法,我在后台再三确认后,我发现这样的架构师真是害人不浅)。这样做最大的问题是——监控系统将在一种低效的状态下工作。监控系统需要把所有的网络请求包打开后才知道是否是错误,而且完全不知道是调用端出错还是服务端出错,于是一些像重试或熔断这样的控制系统完全不知道怎么搞(如果是 4xx错,那么重试或熔断是没有意义的,只有 5xx 才有意义)。**有时候,我会有种越活越退步的感觉,错误码设计这种最基本最基础的东西为什么会没有?并且一个公司会任由着大家乱来?这些基础技能怎么就这样丢掉了?** 还有,我还见过一些公司,他们整个组织没有一个统一的用户 ID 的设计,各个系统之间同步用户的数据是通过用户的身份证 ID,是的,就是现实世界的身份证 ID,包括在网关上设置的用户白名单居然也是用身份证 ID。我对这个公司的内的用户隐私管理有很大的担忧。一个企业,一个组织,如果没有标准和规范,也就会有抽象,这一定是要出各种乱子的。 下面,我罗列一些你需要注意的标准和规范(包括但不限于): - **服务间调用的协议标准和规范**。这其中包括 Restful API路径, HTTP 方法、状态码、标准头、自定义头等,返回数据 JSon Scheme……等。 - **一些命名的标准和规范**。这其中包括如:用户 ID,服务名、标签名、状态名、错误码、消息、数据库……等等 - **日志和监控的规范**。这其中包括:日志格式,监控数据,采样要求,报警……等等 - **配置上的规范**。这其中包括:操作系统配置、中间件配置,软件包……等等 - **中间件使用的规范**。数据库,缓存、消息队列……等等 - **软件和开发库版本统一**。整个组织架构内,软件或开发库的版本最好每年都升一次级,然后在各团队内统一。 这里重要说一下两个事: - **Restful API 的规范**。我觉得是非常重要的,这里给两个我觉得写得最好的参考:[Paypal](https://github.com/paypal/api-standards/blob/master/api-style-guide.md) 和 [Microsoft](https://github.com/microsoft/api-guidelines) 。Restful API 有一个标准和规范最大的好处就是监视可以很容易地做各种统计分析,控制系统可以很容易的做流量编排和调度。 - **另一个是服务调用链追踪**。对于服务调用链追踪来说,基本上都是参考于 [Google Dapper](https://research.google/pubs/pub36356/) 这篇论文,目前有很多的实现,最严格的实现是 [Zipkin](https://zipkin.io/),这也是 Spring Cloud Sleuth 的底层实现。Zipkin 贴近 Google Dapper 论文的好处在于——无状态,快速地把 Span 发出来,不消耗服务应用侧的内存和 CPU。这意味着,监控系统宁可自己死了也不能干扰实际应用。 - **软件升级**。我发现很多公司包括 BAT,他们完全没有软件升级的活动,全靠开发人员自发。然而,这种成体系的活动,是永远不可能靠大众的自发形成的。一个公司至少一年要有一次软件版本升级的review,然后形成软件版本的统一和一致,这样会极太简化系统架构的复杂度。 #### 重视架构扩展性和可运维性 在我见过很多架构里,技术人员只考虑当下,但从来不考虑系统的未来扩展性和可运维性。所谓的管生不管养。如果你生下来的孩子胳膊少腿,严重畸形,那么未来是很难玩的。因为架构和软件不是写好就完的,是需要不断修改不断维护的,80%的软件成本都是在维护上。所以,如何让你的架构有更好的扩展性,可以更容易地运维,这个是比较重要的。所谓的扩展性,意味着,我可以很容易地加更多的功能,或是加入更多的系统,而所谓可运维,就是说我可以对线上的系统做任意的变更。扩展性要求的是有标准规范且不耦合的业务架构,可运维性要求的则是可控的能力,也就是一组各式各样的控制系统。 - **通过服务编排架构来降低服务间的耦合**。比如:通过一个业务流程的专用服务,或是像 Workflow,Event Driven Architecture , Broker,Gateway,Service Discovery 等这类的的中间件来降低服务间的依赖关系。 - **通过服务发现或服务网关来降低服务依赖所带来的运维复杂度**。服务发现可以很好的降低相关依赖服务的运维复杂度,让你可以很轻松的上线或下线服务,或是进行服务伸缩。 - **一定要使用各种软件设计的原则**。比如:像SOLID这样的原则(参看《[一些软件设计的原则](https://coolshell.cn/articles/4535.html)》),IoC/DIP,SOA 或 Spring Cloud 等 架构的最佳实践(参看《[SteveY对Amazon和Google平台的吐槽](https://coolshell.cn/articles/5701.html)》中的 Service Interface 的那几条军规),分布式系统架构的相关实践(参看:《[分布式系统的事务处理](https://coolshell.cn/articles/10910.html)》,或微软件的 《[Cloud Design Patterns](https://docs.microsoft.com/en-us/azure/architecture/patterns/)》)……等等 #### 对控制逻辑进行全面收口 所有的程序都会有两种逻辑,一种是业务逻辑,一种是控制逻辑,业务逻辑就是完成业务的逻辑,控制逻辑是辅助,比如你用多线程,还是用分布式,是用数据库还是用文件,如何配置、部署,运维、监控,事务控制,服务发现,弹性伸缩,灰度发布,高并发,等等,等等 ……这些都是控制逻辑,跟业务逻辑没有一毛钱关系。控制逻辑的技术深度会通常会比业务逻辑要深一些,门槛也会要高一些,所以,最好要专业的程序员来负责控制逻辑的开发,统一规划统一管理,进行收口。这其中包括: - **流量收口**。包括南北向和东西向的流量的调度,主要通过流量网关,开发框架 SDK或 Service Mesh 这样的技术。 - **服务治理收口**。包括:服务发现、健康检查,配置管理、事务、事件、重试、熔断、限流……主要通过开发框架 SDK – 如:Spring Cloud,或服务网格Service Mesh等技术。 - **监控数据收口**。包括:日志、指标、调用链……主要通过一些标准主流的探针,再加上后台的数据清洗和数据存储来完成,最好是使用无侵入式的技术。监控的数据必须统一在一个地方进行关联,这样才会产生信息。 - **资源调度有应用部署的收口**。包括:计算、网络和存储的收口,主要是通过容器化的方案,如k8s来完成。 - **中间件的收口**。包括:数据库,消息,缓存,服务发现,网关……等等。这类的收口方式一般要在企业内部统一建立一个共享的云化的中间件资源池。 对此,这里的原则是: - **你要选择容易进行业务逻辑和控制逻辑分离的技术**。这里,Java 的 JVM+字节码注入+AOP 式的Spring 开发框架,会带给你太多的优势。 - **你要选择可以享受“前人种树,后人乘凉”的有技术红利的技术**。如:有庞大社区而且相互兼容的技术,如:Java, Docker, Ansible,HTTP,Telegraf/Collectd…… - **中间件你要使用可以 支持HA集群和多租户的技术**。这里基本上所有的主流中间件都会支持 HA 集群方式的。 #### 不要迁就老旧系统的技术债务 我发现很多公司都很非常大的技术债务,这些债务具体表现如下: - **使用老旧的技术**。比如,使用HTTP1.0, Java 1.6,Websphere,ESB,基于 socket的通讯协议,过时的模型……等等 - **不合理的设计**。比如,在 gateway 中写大量的业务逻辑,单体架构,数据和业务逻辑深度耦合,错误的系统架构(把缓存当数据库,用消息队列同步数据)……等等 - **缺少配套设施**。比如,没有自动化测试,没有好的软件文档,没有质量好的代码,没有标准和规范……等等 #### 不要依赖自己的经验,要依赖于数据和学习 有好些人来找我跟我说他们的技术问题,然后希望我能够给他们一个答案。我说,我需要了解一下你现有系统的情况,也就是需要先做个诊断,我只有得到这些数据后,我才可能明白真正的原因是什么 ,我才可能给你做出一个比较好的技术方案。我个人觉得这是一种对对方负责的方法,因为技术手段太多了,所有的技术手段都有适应的场景,并且有各种 trade-off,所以,只有调研完后才能做出决定。这跟医生看病是一样的,确诊病因不能靠经验,还是要靠诊断数据。在科学面前,所有的经验都是靠不住的…… 另外,如果有一天你在做技术决定的时候,开始凭自己以往的经验,那么你就已经不可能再成长了。人都是不可能通过不断重复过去而进步的,人的进步从来都是通过学习自己不知道的东西。所以,千万不要依赖于自己的经验做决定。做任何决定之前,最好花上一点时间,上网查一下相关的资料,技术博客,文章,论文等 ,同时,也看看各个公司,或是各个开源软件他们是怎么做的?然后,比较多种方案的 Pros/Cons,最终形成自己的决定,这样,才可能做出一个更好的决定。 #### 千万要小心 X – Y 问题,要追问原始需求 对于 [X-Y 问题](https://coolshell.cn/articles/10804.html),也就是说,用户为了解决 X问题,他觉得用 Y 可以解,于是问我 Y 怎么搞,结果搞到最后,发现原来要解决的 X 问题,这个时候最好的解决方案不是 Y,而是 Z。 这种 X-Y 问题真是相当之多,见的太多太多了。所以,每次用户来找我的时候,我都要不断地追问什么是 X 问题。 比如,好些用户都会来问我他们要一个大数据流式处理,结果追问具体要解决什么样的问题时,才发现他们的问题是因为服务中有大量的状态,需要把相同用户的数据请求放在同一个服务上处理,而且设计上导致一个慢函数拖慢整个应用服务。最终就是做一下性能调优就好了,根本没有必要上什么大数据的流式处理。 我很喜欢追问为什么 ,这种追问,会让客户也跟着来一起重新思考。比如,有个客户来找我评估的一个技术架构的决定,从理论上来说,好像这个架构在用户的这个场景下非常不错。但是,这个场景和这个架构是我职业生涯从来没有见过的。于是,我开始追问这个为什么会是这么一个场景?当我追问的时候,我发现用户都感到这个场景的各种不合理。最后引起了大家非常深刻的研讨,最终用户把那个场景修正后,而架构就突然就变成了一个常见且成熟的的模型…… #### 激进胜于保守,创新与实用并不冲突 我对技术的态度是比较激进的,但是,所谓的激进并不是瞎搞,也不是见新技术就上,而是积极拥抱会改变未来的新技术,如:Docker/Go,我就非常快地跟进,但是像区块链或是 Rust 这样的,我就不是很积极。因为,其并没有命中我认为的技术趋势的几个特征(参看《[Go,Docker 和新技术](https://coolshell.cn/articles/18190.html) 》)。当然,我也不是不喜欢的就不学了,我对区块链和 Rust 我一样学习,我也知道这些技术的优势,但我不会大规模使用它们。另外,我也尊重保守的决定,这里面没有对和错。但是,我个人觉得对技术激进的态度比起保守来说有太多的好处了。一方面来说,对于用户来说,很大程度上来说,新技术通常都表面有很好的竞争力,而且我见太多这样成功的公司都在积极拥抱新的技术的,而保守的通常来说都越来越不好。 > [GO语言、DOCKER 和新技术](https://coolshell.cn/articles/18190.html) > > 当然,一个技术能不能发展起来,关键还要看三点。 > > - **有没有一个比较好的社区。**像 C、C++、Java、Python 和 JavaScript 的生态圈都是非常丰富和火爆的。尤其是有很多商业机构参与的社区那就更为人气爆棚了,比如 Linux 的社区。 > - **有没有一个工业化的标准。**像 C、C++、Java 都是有标准化组织的。尤其是 Java,其在架构上还搞出了像 J2EE 这样的企业级标准。 > - **有没有一个或多个杀手级应用。**C、C++ 和 Java 的杀手级应用不用多说了,就算是对于 PHP 这样还不能算是一个好的编程语言来说,因为是 Linux 时代的第一个杀手级解决方案 LAMP 中的关键技术,所以,也发展起来了。 > > 上述的这三点是非常关键的,新的技术只需要占到其中一到两点就已经很不错了,何况有的技术,比如 Java,是三点全占到了,所以,Java 的发展是如此好。当然,除了上面这三点重要的,还有一些其它的影响因素,比如: > > - **学习曲线是否低,上手是否快。**这点非常重要,C++ 在这点上越做越不好了。 > - **有没有一个不错的提高开发效率的开发框架。**如:Java 的 Spring 框架,C++ 的 STL 等。 > - **是否有一个或多个巨型的技术公司作为后盾。**如:Java 和 Linux 后面的 IBM、Sun…… > - **有没有解决软件开发中的痛点。**如:Java 解决了 C 和 C++ 的内存管理问题。 > > 用这些标尺来量一下 Go 语言,我们可以清楚地看到: > > - Go 语言容易上手; > - Go 语言解决了并发编程和写底层应用开发效率的痛点; > - Go 语言有 Google 这个世界一流的技术公司在后面; > - Go 语言的杀手级应用是 Docker,而 Docker 的生态圈在这几年完全爆棚了。 ### Misc - [On Volitional Philanthropy](https://www.notion.so/On-Volitional-Philanthropy-6bc1a2c94546440ea24c0f8835cd1f6f) - Michael Nielsen 是居住在旧金山的量子物理学家,科学作家和计算机编程研究员。也是一个多产的作家,在[推特上有5.7万fo](https://twitter.com/michael_nielsen)。 这篇文章是几年前他发表在 Facebook 上的一篇短文,标题 Volitional Philanthropy 的意思,用他自己的话来说,是帮助他人扩展在世上存活的方式的范围。用人话来讲,就是开启他人的潜能。 - [The Goal is Resonance](https://www.notion.so/The-Goal-is-Resonance-08430d98a05348a58d5045f29b878296) - 创作就是为了引起共鸣。 - [Cover the Canvas](https://happynotion.notion.site/Cover-the-Canvas-fc87219e88d4de58215fbcae5d7489b) - Cover the Canvas,先填满白纸,先攻下都城,先擒下贼王,都是同样的道理。 - [ Average color of each country (using satellite imagery)](https://eox.at/2021/08/average-colors-of-the-world/) ([eox.at](https://news.ycombinator.com/from?site=eox.at)) - ![img](https://raw.githubusercontent.com/Phalacrocorax/memo-image-host/master/PicGo/worldmap.png) - [octoverse.github.com](https://octoverse.github.com/#lets-look-back-at-the-code-and-communities-built-on-git-hub-this-year) - 73M+Total developers on GitHub - 16M+New users in 2021 - 84%of Fortune 100 companies use GitHub Enterprise - 170MPull requests merged - [Berkeley Packet Filter](https://www.kernel.org/doc/html/latest/bpf/index.html) (BPF) - [想深入钻研一门语言 请大家出出主意](https://www.v2ex.com/t/823731?p=2) - 1 支持**多范式编程**,表达能力强大 2 充分隐藏**计算机体系结构的细节**,特别是内存管理等等的细节 3 **生态丰富**,有大量的工具和库 4 **语法设计**现代,代码较为简洁,开发效率高 5 具有先进的 完善的**工具链支持** 比如 编译器 IDE 调试工具 运行监测工具之类 - ``` Python ====== 算是很多非职业程序员会学习的编程语言,在脚本语言这行里发迹比较早,所以很多 Linux 发行版都会有它。语法中规中矩,除了缩进表示代码层级这点有争议,语言上其他没有让人很恶心的地方,也没有什么难以割舍。Python 比较常用的领域有 C++项目的构建系统、人工智能、若干系统维护的工作,还有一些 Web 项目会用 Python 做。比较大的优点是容易找到有 Python 的环境以及至少会点 Python 的人。 Java ====== 用「永远的神」来形容 Java 是没什么问题的。几十年的生态积累非常庞大,如果用它做项目也几乎不用担心招不到人这个问题。Spring 等框架过于复杂,还有 Java 做的桌面程序性能不佳等毛病,让大家对 Java 印象不太好。不过连 Golang 都可以有泛型,那 Java 自然也是可以现代化的。也算是和 Python 挺像,在各自的领域里中规中矩,如果真的不知道选什么,那选它不会有啥大错。多年来许多人觉得 Java 和 C++是竞争对手,至少在今天事实并非如此,它们的优点几乎不重合。 C♯ ====== 最早是以 Better Java 的形象出道的,时至今日似乎已经走出一条自己的路。曾经有个笑话,说 C♯为什么没有 Spring 这种框架,答案是因为微软没有春天。还有个笑话是说 Java 程序员都戴眼睛,因为他们 can’t see sharp 。这俩笑话其实反映出 C♯的特点,就是语言特性远比 Java 丰富,写起来更爽,但生态不够好,招人更难。如果单纯为学习目的,C♯很值得了解,毕竟其父是 Anders Hejlsberg ,编译器领域上古大佬。 JavaScript ====== 一说是披着 Java 语法皮的 Lisp ,几乎绕不开的语言。早年乏善可陈,除了原型继承和对象模型和其他语言差异较大值得了解。因为赶上好时代,一方面性能在各家军备竞赛下彻底高出其他脚本语言一个档次,另一方面各种语言变种层出不穷试图弥补其语言缺陷。到今天算是强大的现代语言,还自带可能是地球上最丰富的库和工具生态( Java 人家至少没什么人天天想着拿 AST 搞事)。不是你想不想学的问题,时至今日做开发没法绕过它,而且在几乎所有主流平台上都能找到自带的 JavaScript 运行时。这个圈子的程序员一个比一个能整活,人称码农娱乐圈。 PHP ====== 「最好的语言」,最早就是一个能编程的模版引擎,Web 领域干简单的活没人比它更快,LAMP 这个缩写简直是一个时代的回忆。后来 PHP 也加了很多东西,包括模仿 Rails 的 Laravel 以及 Swoole ,不过不妨碍大家还是按照它曾经的定位玩。语言方面可以玩的不算多。 ``` - [记住这三点,你的职场晋升之路将畅通无阻](https://www.huxiu.com/article/484049.html?f=wangzhan) - 战略/人才/组织 一喊二要三内耗 - 重视风险胜过产出。 - [go 语言如何进阶?](https://www.v2ex.com/t/806528#reply4) ``` 1. goroutine 的使用 2. tcp / udp 基础 3. 协议封包 4. 客户端服务端通信 5. 锁的使用 6. 自定义包的使用 7. cli 应用 8. 系统插件设计 9. 数据统计和第三方插件集成 10. 跨平台的发布 frp ,go-shadowsocks2 , nps, v2ray, 类似的项目都不错,可以重点的参考 frp,有些思路还满不错的 ```