码农戏码

新生代农民工的自我修养

0%

Twitter上有人发了一个推,说他之前问过一个问题:“你最好的一条职业建议是什么?”,他得到了1300多个答案,最后他整理了12条最好的建议。
🔗 twitter、com/chrishlad/status/1502650707274608644

1、 尽可能为别人减少不确定性

  • Uber解决了打车的不确定性
  • 亚马逊解决了送包裹的不确定性
  • 你也可以通过及时更新项目进展来帮老板解决不确定性

2、 公司比职位更重要

3、 一旦接受了一个任务,无论多小或者多么不起眼,要把它做的特别好,超出别人的预期。这样你就能建立起一个良好的声誉,让别人知道你总能高质量的完成工作。当你建立了这种声誉,你就能得到更多的机会,更大的知名度,以及更大的成功。

4、 如果我不能信任你,你再聪明都没用。

5、 在你的职业生涯中,陪你走到最后的只有你自己。不是你的公司,不是你的经理,不是你的团队,只有你自己。
在做你所有职业生涯的决定时,优先考虑你自己。

6、 影响你职业生涯的三件事:

  • 你做什么?(工作)
  • 你为谁工作?(客户)
  • 和你一起工作的人是谁?(团队)

如果你热爱你的工作、客户和团队,你会非常非常幸运。

7、 和一个聪明的能激励你走向伟大的人结婚。

8、 要么能学东西,要么能赚钱。
否则果断离职,去找一个这两者至少占一样的工作。

9、 如果一个问题你不问,那么答案一定是“不”。

10、 选择你的老板。
你有权选择谁当你的老板,而在找工作的过程中很多人没有考虑到这一点。
一个优秀的老板可以为你的职业发展提供极大的助力。

11、 学会阐明你所做的事情的商业价值,而不仅仅是你的工作头衔或者项目。
不好的例子:“我是一个数据科学家。我创建了3个自服务数据应用”
更好的例子:“我帮助管理层发现了一个可以节约2300万美元成本的机会”

12、 “职业”,本质是一个营销名词,是由那些经营特定类别的梦想的人卖给你的,而他们在贩卖这个梦想时赚了很多钱。
赚钱,承担风险,有冒险精神。
但不要让“职业”来限制自己

在做程序测试时,常会用到测试替身来协助我们快速完成测试。

有时候被测试系统(system under test(SUT))很难测试,因为在测试环境下依赖的组件不能正常使用。如外部系统。

当在一个不能使用真实依赖组件(depended-on component(DOC))的地方写test时,我们可以使用Test Double

Read more »

几乎在每个团队,都至少有一份代码规范,或者代码的check list。然也就仅仅是一份清单。

每次团队复盘时,都会有一条,我们要写好代码,然“好代码”是什么样子,什么标准,全取决于各人的水平。

每个程序员也都知道code review的重要性,然排期很紧张,难得做一次。宁可花时间追查问题,也不做防御性准备。

这些现象,是不是特别平常,虽然很想改变,但又是无力感呢。

程序员对代码的追求态度决定了职业生涯的高度,代码的质量决定了生活质量。

为什么会有上面提到的现象,大概有这两方面的原因:

1、每个人对“好代码”的观念不一样

2、对于“坏味道”缺乏明确的表象判断,也就很难提出明确的改进措施

Read more »

先看一段简单的代码:

1
2
3
4
5
6
7
8
package com.zhuxingsheng.adapter

@PostMapping("/login")
public LoginResponse login(LoginRequest loginRequest) {

return loginService.login(loginReqeust);

}

从代码中,可以明显看出这是一段处理登陆请求的方法。在大多数项目中,这种代码很常见。

它有什么坏味道呢?

分层穿透了,LoginRequest类本应该属于入口层,结果穿透到了service层。

细细追究,需要明确的问题:

1、LoginRequest到底属于哪一层,是resource层,还是service层?

2、没有达到DDD防腐层的意义,resource是隔离外部与核心业务的,但却变成了透传。

Read more »

“学而优则仕”的传统文化渗透在各行各业。

那么”码而优则仕”则是这种文化的延伸,自然而然的结果。

当然很多程序员对做管理不感兴趣,想很纯粹的研究技术,成为一名技术专家。人各有志,但客观讲,技术专家与技术管理相比较,成为技术专家比技术管理难度大得多,只有做到在一个区域,一个行业屈指可数的顶尖专家,才有更加广阔的前景。尤其在国内的环境大多数都是业务型公司,技术本身没有直接价值,没有太高的壁垒,有太多能取代你位置的人。

当然,技术管理也有难度,尤其对于程序员群体。但只要做到一个团队内的最佳,则拿到了敲门砖,随时准备幸运之神的降临。跨越技术纯粹性的舒适性,技术管理之路就开启了。

Read more »

使用缓存来加速应用程序的访问速度,是几乎所有高性能系统都会采用的方法。

但缓存真的那么好吗?架构师在构建高性能系统时,是不是必须增加缓存组件?缓存是不是多多益善?

《一代宗师》里本山大叔说过这样的一段话:

“一门里,有人当面子,就得有人当里子。面子不能沾一点儿灰尘。流了血,里子得收着,收不住,漏到了面子上,就是毁派灭门的大事。”

如果缓存是里面的角色,那么绝对是面子。

虽然缓存带来了性能的提升,但给系统带来的多少复杂性。缓存穿透,缓存击穿,缓存雪崩,缓存污染这些问题不绝于耳。这些问题不是操作系统兜着,就是程序员。所以缓存是24K纯金的面子。人人都好面子,还得有个能轻松应对的里子。

Read more »

微服务架构已经很流行了,并且有大量文章描述相对单体架构,微服务架构带来的众多优点。

怎么从单体架构更优雅地转化为微服务架构呢?

有一种被实践证明有效的方法论:The Twelve-Factor App

1、Codebase

一份基准代码,多份部署

尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份 部署 相当于运行了一个应用的实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署

2、Dependencies

显式声明依赖关系

12-Factor规则下的应用程序不会隐式依赖系统级的类库。 它一定通过依赖清单 ,确切地声明所有依赖项

3、配置

在环境变量中存储配置

通常,应用的配置在不同部署 (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括:

  • 数据库,Memcached,以及其他 后端服务 的配置
  • 第三方服务的证书,如 Amazon S3、Twitter 等
  • 每份部署特有的配置,如域名等

有些应用在代码中使用常量保存配置,这与12-Factor所要求的代码和配置严格分离显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。

4、后端服务

把后端服务(backing services)当作附加资源

后端服务是指程序运行所需要的通过网络调用的各种服务,如数据库(MySQL,CouchDB),消息/队列系统(RabbitMQ,Beanstalkd),SMTP 邮件发送服务(Postfix),以及缓存系统(Memcached)。

每个不同的后端服务是一份 资源 。例如,一个 MySQL 数据库是一个资源,两个 MySQL 数据库(用来数据分区)就被当作是 2 个不同的资源。12-Factor 应用将这些数据库都视作 附加资源 ,这些资源和它们附属的部署保持松耦合。

5、构建,发布,运行

基准代码 转化为一份部署(非开发环境)需要以下三个阶段:

  • 构建阶段 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包 依赖项,编译成二进制文件和资源文件。
  • 发布阶段 会将构建的结果和当前部署所需 配置 相结合,并能够立刻在运行环境中投入使用。
  • 运行阶段 (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序 进程。

12-factor 应用严格区分构建,发布,运行这三个步骤。 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。

6、进程

以一个或多个无状态进程运行应用

运行环境中,应用程序通常是以一个和多个进程运行的。

12-Factor 应用的进程必须无状态且无共享。 任何需要持久化的数据都要存储在后端服务内,比如数据库。

7、端口绑定

通过端口绑定(Port binding)来提供服务

互联网应用有时会运行于服务器的容器之中。例如 PHP 经常作为 Apache HTTPD 的一个模块来运行,正如 Java 运行于 Tomcat 。

12-Factor 应用完全自我加载 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 通过端口绑定来提供服务 ,并监听发送至该端口的请求。

8、并发

通过进程模型进行扩展

任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP 进程作为 Apache 的子进程存在,随请求按需启动。Java进程则采取了相反的方式,在程序启动之初 JVM 就提供了一个超级进程储备了大量的系统资源(CPU和内存),并通过多线程实现内部的并发管理。上述2个例子中,进程是开发人员可以操作的最小单位。

9、易处理

快速启动和优雅终止可最大化健壮性

应用程序的进程应该是一次性的,以便它们可以快速启动、停止和重新部署,而不会丢失数据。这有助于快速弹性扩展、代码和配置更改的快速部署以及生产部署的稳健性。

10、开发环境与线上环境等价

尽可能的保持开发,预发布,线上环境相同

从以往经验来看,开发环境(即开发人员的本地 部署)和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面:

  • 时间差异: 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。
  • 人员差异: 开发人员编写代码,运维人员部署代码。
  • 工具差异: 开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。

12-Factor 应用想要做到 持续部署 就必须缩小本地与线上差异。 再回头看上面所描述的三个差异:

  • 缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。
  • 缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。
  • 缩小工具差异:尽量保证开发环境以及线上环境的一致性。

11、日志

把日志当作事件流

将日志流式传输到选定的位置,而不是将它们转储到日志文件中。日志可以定向到任何地方。例如,它们可以被定向到 NoSQL 中的数据库、另一个服务、存储库中的文件、日志索引和分析系统或数据仓库系统。

12、管理进程

后台管理任务当作一次性进程运行

将管理任务与应用程序的其余部分分开,以防止一次性任务导致正在运行的应用程序出现问题。容器使这很容易,因为可以启动容器只是为了运行任务然后将其关闭。

最近看完了一本大佬很早就推荐的书:《演进式架构》

现在看已经算是一本很老的书了,里面的很多概念对架构师来讲已经算是耳熟能详了。

如果你没有一些常识性思考,那还是可以看看的,如果没有时间,我通过这篇读书笔记梳理了书中的核心知识点,结合最近的一些新书观点,方便你快速获取这些知识。

Read more »

《程序员软技能》中,提到过一种思维,要把自己当成一家企业,而就职公司是我们的客户。

既然如此,我想需要考虑的最重要的事情应该是我给客户提供了什么产品,产品是什么价格?

对于程序员来讲,提供的最根本产品自然是代码,我们现在需要考虑的事就是代码的价格,平均到基本单位,就是每一行代码值多少钱?

当下市场,先考虑一下代码语言种类:

使用java语言写的一行代码

使用go语言写的一行代码

使用python语言写一行代码

亦或写一行sql

甚至调试一个AI模型参数

这些代码它们的价格肯定是不一样的。想到的第一个因素估计是写的人不一样。都写相同的语言代码,什么在决定价格?自然是写代码程序员的水平了。如同时期研究生相对本科生自然值钱些。

即使都是出于同一人之手。那么是什么决定了价格?是因为牛逼吗?

PHP是最好的语言?从高维度讲sql man与AI调试师没什么不同,那决定价格的最根本因素是什么?

在市场上,决定价格的最重要因素是需求

现在写一行VB语言会比java语言值钱吗?不是VB语言不好,终究是因为市场需求。当更先进更高阶的技术出现,更能满足市场需求时,价格自然上涨。这也是为什么苦逼程序员必须随着技术更迭不停地学习。甚至要预判技术趋势,提前投入精力学习。才能保障自己写的代码价值不被贬值。

除了市场需求因素,程序员水平,还有什么因素呢?我们还需要考虑哪些问题?

把需求换种说法,就是写的代码是否有用?

从关注程序员自身来讲,可以考虑再深入点:

1、我写的代码对别人有没有用呢?

写个hello world,或者写了个微信,似乎都有用

2、我写的代码对别人有用的话,有多大用处呢?如何做到最有用?

hello world作用可以作教程,对小白编程基础培训,微信可以通讯、支付、摇一摇,似乎用处都不小。因此它们的作用不能从程序员侧考虑,而得从客户侧考虑。

3、我写的代码对别人有用的话,对多少人有用?如何做到对更多人有用?

hello world面对的人群是刚要入门编程人员,而微信是全民应用;要想对更多人有用,全民编程似乎不太可能

4、我写的代码对别人有用的话,在多长时间段对别人有用呢?如何做到让这个时段更长些

除了上面的问题,还需要从客户侧考虑,不能只是埋头写一行行的代码,还得考虑客户的需求,这样又需要考虑一些问题:

1、他们真正的需求是什么?最需要的是什么?

需要程序员?需要35岁以下的程序员?

2、我是那个能满足他们需求的人吗?

在优化人员时,优化名单上会出现你的名字吗?

3、如果我能,我有没有可能成为必需?

4、如果我不能,我怎样才能?

5、有必要一定由我去满足他们的需求吗?

这么多的问题,总结成一句话,行动指南:挑最需要的事情做,自然就成了最被需要的人。


常听些大佬讲,要有商业sense,而一切商业模式的根本,怎么赚钱,赚什么钱,赚多少钱。

在现如今充满物质喧嚣的大环境中,总包、副业刚需、内卷这些词时时充斥我们时,更应该考虑下商业底层逻辑。

我想作为程序员,“我的一行代码值多少钱?”,这个问题是最基本的商业sense。

这些年中台、微服务都是技术浪潮中的弄潮儿。两者的命运似乎是所有技术新词的缩影:先谈,再建,后拆,最后平静。

如中台,开始时聊什么都得带上中台,战略层喜欢谈,执行层也喜欢谈,再后面跟随一线大厂纷纷搭建自己的中台,然后就是反思,拆除中台,最后平静看待中台。

中台可以说已经经历完整的生命周期,而微服务周期也差不多,但对于“拆掉”,两者的声势与目标却不太相同。

《中台是什么》中提出,“效能下限”与“创新上限”就像翘翘板,产生了哑铃效应,而中台则是追求效能的极致,同时却也降低了创新上限

建中台是为了效能,拆中台是为了创新。

以阿里为代表的大厂对拆中台真是高举高打,但看看微服务,可没哪个大厂高喊要拆掉微服务,可见他们俩还是有本质差别的。

更神奇的是,不管是拆微服务还是拆掉微服务,本质需求却是一致的:提升效能

为什么都是提升效能,从两种行为分别阐述一下

为什么拆分微服务

首先一起回顾一下,为什么要拆分微服务?对于这个问题不得不再向前回退,回到单体架构时代

在微服务架构出现之前,单体架构是永恒,天经地义的。以致于“单体架构”一词都没人提出。

项目起初,单体架构无疑是最佳选择,不仅易于开发、易于测试、易于部署,且由于系统中各个功能、模块、方法的调用都是进程通信,性能是最高的。

甚至在项目从小型发展为中型时,也没有那么不堪。虽然是单体架构,但内部结构并非“铁板一块”,在业务量级可承载范围内,也有一定程度的扩展性。

从两个视角观察扩展性

在纵向角度,绝没有一个项目完全是个“大泥球”形态,至少都会以分层架构风格对代码进行纵向层次划分。

在横向角度,单体架构也支持以功能、技术等维度划分,拆分成各个模块,以便代码重用和管理,甚至提取出各种形体组件,如jar

那拆微服务解决了哪些效能问题?

第一程序效能

在于应用程序的某个方面给基础设施带来了过重负担,这反过来又很可能会导致糟糕的用户体验。

如,图像处理需要大量CPU,如果CPU负载变得非常高,这将会导致应用其他处理资源的饿死现象。影响系统延迟,甚至影响系统可用性。

也就是说应用程序中局部缺陷会造成全局问题。局部间没有隔离能力,一旦出现内存泄漏、线程爆炸、阻塞、死循环等问题,将影响整个程序。不仅导致单个功能不可用,甚至整个程序的效能都降至为零。

从程序维护性来说,所有代码都在同一进程,无法做到单独停止、更新、升级某一部分代码。只能制定专门停机更新计划,整体做灰度发布,A/B测试。

第二团队效能

与应用的关系不大,但关系到如何组织团队。在应用程序的特定部分,投入工作的人越多,开发和部署就会越慢,而且越容易出错。

如,抢占持续部署同一服务,出现排队现象,意味着本可以交付产品的工程师只能坐等轮到他们进行部署。出事“紧急事件”时,多个团队代码都需要回滚。

综上所述,简单总结一下,单体架构并不是一无是处,项目起始阶段依然是最佳选择;

当对应用程序性能要求超过单机能力,以及软件的开发人员规模明显超过了“2 Pizza Team”时,
不管是程序效能还是团队效能都已经达到瓶颈,此时可以通过微服务架构来解决这些问题。

微服务怎么解决效能问题?

对于程序效能,在单体架构时代,想要整体系统的可靠性,我们只能努力让每一个模块,每一行代码都可靠,以达到整体系统的最终可靠性。

然而常常事与愿违,战术层面再优秀,也难以弥补战略层面的缺陷。在构建大规模系统时,人们的观念也从“尽量不出错”向正视“出错是必然”转变,在此前提下,历史悠久的单体架构终被挑战。

微服务把独立的单体架构内部依赖组件,由“编译时期”推迟到了“运行时期”,对时间维度的解耦,带来了运行时动态扩展、服务间技术异构、服务独立交付等好处。

也就解决了上面所述的局部间没有隔离能力造成的全局性故障,导致整体程序效能降至为零的情况。也实现了局部维护的能力,提升系统整体可维护性,保障系统整体可靠性与可用性。

对于团队效能,系统不再是一块整体,团队更加独立地工作,独立地部署,从而发布更多产品。

尤其在康威定律的指导下,划分组织边界以及服务职责范围,让组织之间更高效默契的沟通以及相互配合提升整体效益。

为什么拆掉微服务

微服务的确带来了很大的收益,不管在系统扩展性,还是在组织扩展性,都促使商业最大限度的规模化。

然业务不是永远增长的,随着业务增长乏力,收益萎缩,需要探索新商业机会,原先高成长的业务团队规模也慢慢收缩,之前的服务系统也慢慢沦为遗留系统。

从原先增长期的每个系统0.5人,到维护期每个人10个系统,服务与团队与康威定律极度不匹配。

简而言之,在高增长期康威定律带来的所有收益,随着时间的推移,业务收缩,都变成了“遗留”团队的负债。

所以需要拆掉微服务,改变服务边界以匹配团队边界,平稳回归康威定律。当然也不是彻底拆掉所有微服务回归单体架构。重点是重新调整职责范围,拆分成符合团队的服务边界。

此时再回头看微服务概念时,当初纠结的“微”到底是多大的问题,已经完全不重要。微服务只是相对单体架构(Monolithic)的称呼,“微”不代表任何实际的内容。

我们需要更多的关注“合适大小”,服务经过了恰当地设计,以满足其需求:它负责“合适数量”的功能。而且,至于什么是“合适”并不是一个静态的概念,它取决于团队,即团队的技能集、组织的状态、投资回报率(return-on-investment,ROI)的计算、持有成本以及该服务运行的时间点。

简单总结一下,拆掉微服务,相对程序效能,更多的关注点在团队效能,服务边界匹配团队边界。其次,在整合团队,回归康威定律的过程中,业务流量也是在减少的,程序效能问题也再像扩张时期那么显著。

总结

一切技术都得服务于业务,而业务形态决定了技术形态。

没有完美的业务,也必然没有完美的技术,只有两者相匹配时,才能相得益彰。

不管是建,还是拆。都是适时的选择。架构只有顺应环境才能生存,最大化业务价值。

参考

拆掉微服务