2020年的总结

2020年对于地球来说是不平凡的一年。年初爆发了 COVID-19 病毒,全球基本上就处于了封锁的状态。紧接着之后又发生了很多不好的事情,这些都可以从维基百科查到,我就不用来占用这篇博客的字数了。

年初我和欣和大多数人一样,居家隔离。每天就是在晚上订菜,做饭,在家办公。谁能想到,2020年的最后一天,我现在在赤道附近30多度的天气里面写这篇年终的总结。

说起总结,今年好像没有什么好总结的。一切都过得非常平凡,甚至可以说有一些碌碌无为。只有一两件事情可以说说。

第一件,我结婚了。这件事情可以让 2020 年成为我人生的一个分割线。从今年起,我就不再是一个人了。剩下的人生可以有一个人一起走完。

第二件,就是离开了阿里巴巴。其实在刚开始加入阿里巴巴的时候,我就觉得这家公司不适合我。但是又说不上是哪里的问题,我到底想要什么。这几年就试图找到自己想要的东西。

在这个博客的草稿箱躺着一篇文章,计划着离职之后发出来。(一家公司的员工只有在离职之后才能说话,这是一个悲哀)。以为我在离职的时候会有什么轰轰烈烈的原因,其实并没有。想明白了自己想要什么,就离开了。非常简单和平静。以至于这篇文章现在看来都没有发布的必要,写完之后就删掉了。

其实面试一直是在进行中的。只要一家公司做的事情以及对待员工不是特别地没有道德,我一般都会参加面试。通过面试过程再决定要不要加入。所以可以说是一个双向选择的过程。我觉得即使最后没有通过面试或者拒绝offer,但是通过面试的过程也可以学到东西,和面试官交流经验。

因为知道选择一份不适合自己的工作会有多大的损失,所以对于下一份工作的选择特别谨慎。我非常喜欢 SRE 的工作,我觉得 SRE 的工作有意义要满足一个必要的条件:SRE 的数量不能随着业务的数量增长,SRE 必须以固定的成本支撑增长的业务。不然的话,就和传统的运维没有本质的区别。我现在的公司的 SRE 数量已经超过了 500 人。以及我经常会问面试官一个问题:您是如何看到 AIOps 的?因为这个问题的答案能反映出我对这家公司(至少是 SRE 团队)的理念是否符合。

今年去面试过的公司有 LeanCloud,今日头条,PingCAP,Shopee。拿到 Offer 的公司有 LeanCloud,今日头条,PingCAP,Shopee。

我觉得 LeanCloud,PingCAP 这两家公司非常值得说一说。我怕很多人不知道中国存在这样优秀的公司,所以在这里打一个广告。

LeanCloud 可以说是中国版的小规模版 Heroku,我没有想到员工数量会这么少,这么少的人做出这样的产品,至少可以说明这里面每一个人都是精英。并且 LeanCloud 有一些理念非常地超前。感兴趣的可以看下他们的公开资料: 开放薪资,以及江宏老师的博客。技术上的选型也比较极客,用的 Clojure, nodejs 等。

PingCAP 是一家做数据库的中国公司,在开源方面做的很好。TiDB 是一个可以水平扩展的数据库,这几年在国内技术上和业务上发展的都很好。现在有很多公司在使用 TiDB 了,比如 Shopee,知乎,一些银行等。除了 TiDB,他们还开源了很多优秀的项目,比如 chaos-mesh等。如果没有开源的基因,这些事无法做的的。PingCAP 不像阿里巴巴做的是弃婴式开源,是真的开源。技术上依然比较极客,非常 Cloud Native,语言主要是 Rust/Go。SRE 团队在做的事情也非常有意思。

最后我选择加入 Shopee。其实最根本的原因,还是现阶段的 Shopee 能满足现阶段的我吧。一个12人的 SRE 团队,负责了从网络到文件系统到存储,到 CMDB 等非常广的方面,需要做的事情有很多,这样让我感到很兴奋:)相比之前的工作,基本上什么事情都有非常多的人在做,之前的事情虽然做过了但并不能说完善,只能说能用的状态。然后大家都不喜欢维护老旧的系统,喜欢在这些系统上包一层或将之进行取代,做出花来,以便晋升。所以我觉得现在的 SRE 团队更加踏实一些。

以上提到的所有公司,如果读者有兴趣,都可以找我内推。但是希望读者最好是对 Shopee 有兴趣。

有关于2020年,其他的事情倒是没有什么好提起的了。我觉得我在 2020 年浪费了很多时间在开会,对着奇怪的设计思考为什么要这个样子,试试证明只是因为组织的架构问题罢了,其实更简单的方案就摆在那里。但总体来说,这也是一段非常宝贵的工作经验吧。至少今年我花了很多时间来思考我要什么,我想成为什么样子的人,我的梦想。

2021年,就继续朝着这个方向努力吧。


往年:

  1. 2013年
  2. 2014年
  3. 2015年
  4. 2016年
  5. 2017年
  6. 2018年
  7. 2019年
 

Devops 中的 Overfitting

在运维工作中,很多人都在宣扬自动化,经过几年的工作,我发现这种自动化在某些地方有些极端了。devops 崇尚自动化,但并不是一味的自动化。有一些事情是适合手工操作的,过度的自动化会浪费跟多的成本,只能得到很少的收益。

就好像一台电梯,用古老的电梯算法运行了很久,但是有一天有人觉得这个电梯运载能力没有发挥到极致,我们可以使用机器学习训练他采用更好的算法。于是就需要更多的人力资源来实现这个项目:一个小组提供训练数据,一个小组来训练新的算法模型,设计一套硬件设施监控和对比运载效率,设计回归的方案评估运载效率的变化,等等……

最终可能发现将原来两台电梯的运载能力变成了相当于2.5台的运载能力,但是这优化出来的0.5台电梯带来的问题有:1)某些情况下的表现可能还不如电梯算法 2)没有人知道现在电梯是怎么运行的了,因为这是机器学习训练出来的模型 3)复杂的算法从上线走向成熟需要持续的维护和优化,稳定性不如原来的电梯算法。等等。其结果还不如就再增加一台电梯。(当然,也可能因为当初楼里的设计结构不允许再增加电梯,软件工作中也有类似的问题。)

最近又看到一个例子:

牙膏厂生产流程会产出没放牙膏的空箱。厂长花8百万请专业顾问,用牛逼的秤测箱子重量,发现空箱就警报并停止流水线,员工手动除空箱。后来秤再也检测不到空箱了,为何?员工自动化了除空箱的步骤:用20元的风扇吹。

source

(这个例子被指出只是一个段子,详见这里。2022年3月更新)

我同意《Google SRE 运维解密》中提到的一个观点:应该尽量避免黑魔法系统。但是“魔法”在大公司中好像非常受追捧。因为将原来人工操作的东西,变成自动化的东西,这对于赢得年终奖、晋升来说,太有说服力了。用20元的风扇吹,这么简单的方案,如何能体现出来你的工作价值,展现你的能力呢?

在很多时候,这种“过度的”自动化,只会产生一些只针对特定场景、特定的 Case 才能发挥出一点作用。我觉得这就是一种 Overfitting。比如很多公司都在做的故障自动定位系统,有一种做法是,当一个故障发生之后,SRE 去写一堆 if-else,实现如下的效果:只有仅当系统 A 出现 X 错误,并且系统 B 执行了 Y 操作的时候,这个故障定位系统能够将问题的根因准确无误的报告出来。但是一模一样的错误,在一个复杂的分布式系统中重新出现一次的概率,又有多少呢?这么做的意义,最多只不过是给领导一个交代罢了:看,虽然这次故障造成了损失,但是如果相同的故障再发生,我们花几分钟就可以恢复了。

之前看到一个从蚂蚁金服的 SRE 离职的员工在博客里失望的说:系统应该是自治的,而不是自动化的。因为是在 CSDN 上看见的,现在找不到原文了。我非常同意他的话。对于自治,我是这么理解的:分布式系统本身应该有一定的错误恢复能力,类似于 Redis Cluster 的 Fail Over. 而不是依靠外部的一些系统去自动化(依赖 if-else 逻辑)判断监控数据或者状态,进行自愈之类的操作。

就像是智能手机出现之前,大部分的黑白屏手机都有一个功能叫做情景模式:选择一个情景模式,就会附带给你设置好铃声、震动、短信提示等。但是我从没见过周围有人使用这个功能。iPhone 出来之后,将提示音的设置做成了一个物理按键,你不再需要记住那么多情景模式下都是什么设置,只有一个按钮,关上之后不会发出声音,就这么简单。我们搞的那些黑魔法系统,背后设置了那么多东西,却无法告诉用户我们到底做了什么,这只会让SRE的心理负担越来越重。(另一个想说的点是,我实际上认为,当前公司的可用性有很大一部分是建立在对员工的心理负担上面的。如果造成P1故障,全年3.25取消年终奖。就算更改一行代码,要经过至少40min,还有层层审批,才能发布。等等)

其实编程中也存在这种 overfitting,和 devops 一个道理,大量的if-else嵌套会让你看不出到底是哪一些逻辑在执行。这会造成代码异常复杂并且难以维护。

想起来 Linus 在谈到代码品味时说的:

对我来说,我愿意与之共事的人, 必须有好的品位,这就是如何…… 我举的这个例子很傻, 没什么意义,因为实在太短。 好的品位体现在更长的代码里。 好的品位体现在能看清全局 甚至有一种直觉, 知道怎么把事情做漂亮。

简单即是美,Unix 提倡每一个工具都做一件事情,这样用户可以将它们自由地组合在一起,完成复杂的任务。但是现在好像大家导出都喜欢做“平台”,喜欢将能想到的所有的东西都涵盖进来,所谓“远大的视角”。我认为作为 SRE,了解所要维护的系统的原理,它是怎么运行的,做好监控,远比去做一些魔法系统收益要大。

一个 SRE 团队中,这种有“品味”的人至关重要。太多的 Overfitting 会将整个团队带向一个无限复杂度的深渊,在这样一条路上无论如何挣扎、怎样加班,最后都会冲下去。

ML for Systems 我感觉在现在业界的情况来看就是伪命题,坑贼深.

–By 某推友

 

程序员如何挑选钻戒

好久没有写博客了,哈哈。最近事情太多,最幸福的就是求婚成功。继我的肥仔同事购买钻戒求婚成功之后,没想到我也要踏上寻找钻石之路了。看了他的那篇文章,给了我一些钻石的基本知识,最终我买了 BlueNile 的裸钻,可以分享一下购买历程,给有需要的朋友。

品牌和裸钻

钻戒基本上分成两种, 一种是品牌的成品钻戒,比如 Tiffany, Cartier, 六福珠宝等。也有裸钻,裸钻的意思是你直接从珠宝商那里购买一个钻石,然后再去购买一个戒托,最后找一个提供加工服务的地方,把它们加工成钻戒。

钻石的议价空间比较大。买裸钻的价格最低,像国内的六福珠宝等,钻戒的价格一般是裸钻最后成品的价格的 1.5倍 – 2倍。奢侈品牌一般是裸钻的 2倍 – 4倍。

bluenile 的钻石挑选页面,品质更好,价钱就更高

那么要不要购买裸钻,就成了一个问题。裸钻的优势是:

  1. 价格便宜,一分钱一分货,基本上没有溢价,价格非常透明;
  2. 你可以亲自挑选一颗特定的钻石,每一颗钻石都是不一样的,钻石商也是通过这一点营销出来钻石的意义;
  3. 可以自己挑选戒托;
  4. 钻石库非常大,15万颗钻石;

裸钻的劣势是:

  1. 等待时间较长。裸钻之所以便宜,就是因为钻石并不是在钻石商手中的现货,网站上供你选择的钻石其实是不同钻石商共享的钻石库。你要先预定上,他们回去帮你购买,最后送到你的手上。像我购买的 Bluenile 就花了 4 个周才到我的手上。国内的钻石小鸟,要求立即拿货的话,要比全球调货的钻石,价格贵 1.5-2倍。并且即使你挑选好了钻石,最后也有 30% 的几率买不到;
  2. 加工成本。就是你要自己选择戒托并且加工。但是现在基本上裸钻厂商都会提供戒托 + 加工的服务了。除了收藏钻石,很少有人直接买钻石了,基本上都是加个戒托,最后拿到手成品。另外要注意的是裸钻提供的戒托以及加工,做工上可能没有奢侈品牌好,比如同样款式的 Tiffany 六爪经典款戒托,Bluenile 的可能爪之类的地方会更显粗大一些;
  3. 无法试戴。Bluenile 提供了一些方法可以测量手寸,并且提供免费修改手寸的服务。所以如果不着急拿货的话,可以接受。

服务方面

无论是裸钻还是品牌厂商,都提供一些服务。但是这些服务有些许猫腻,需要注意:

  • Bluenile:1年内免费调整手寸,1个月内免费退货。用户只需要承担退货运费。购买新的钻戒的话,上次购买的钻戒可以抵100%的现金。但是要注意,这也意味着你购买的钻石可能是别的用户退回的。虽然对于钻石这么坚硬的珠宝来说几乎没有影响;
  • Tiffany:不能退货,免费调整手寸;
  • 其他:可以自己咨询店员;

如何挑选钻石?

来到了最重要的环节了。无论是品牌钻戒还是裸钻,挑选哪一颗钻石,都是买方要面临的问题。

首先介绍一下基本的知识。钻石的品质是由四个指标决定的。一颗钻石的四个指标分别得分如何,一般会有一个 GIA 证书来说明。GIA 是权威的钻石鉴定结构,钻石商为了让钻石的品质得到认可,会付给 GIA 钱,然后把钻石送往 GIA 鉴定所,GIA 将厂商标签删去,平等地评价钻石的品质,最后给钻石出示一个证书。

(小知识:有了 GIA 证书,买到的钻石就一定好吗?也不是。有一种骗局是珠宝商将一颗品质极好的钻石送到 GIA 鉴定,拿到一个证书。GIA 会将证书标号用镭射引到钻石腰上,以做到一颗钻石对应一个证书。但是只要花 500 块钱,就可以将这个编号给抹去。然后珠宝商再次将这颗优秀的钻石送到 GIA,拿到一张新的证书。老的证书就可以搭配品质不好的钻石来买,赚黑心钱。奸商)

在我心中这四个标准按照重要性排序如下:

  1. 切工:对钻石是否闪亮起决定性作用,即使天然品质再好,如果切工不好,折射光的效果大大折扣。所以我挑选钻石只看 3 Excellect 等级切工的钻石。另外,某些钻石商会在 3 Excellent 中再加一个更好的等级,将钻石卖的更贵。就像是得到 80 分以上,GIA 就认为是 Excellent 了。然后 Bluenile 从中挑选出切工 95 分以上的钻石,将它们作为 Astor 品质的钻石;
  2. 大小:就是克拉数。可能是我们平时听到的 “几克拉的钻石” 比较多,但是这个参数的重要性不如切工。并且并非越大就越好,要结合媳妇的手来看,看起来好看才最重要;
  3. 颜色:颜色用字母 D – K 表示,D 最透明,K 有些发黄。我选择的是 E 色,仅次于 D,即使在没有强光下,钻石也看起来很漂亮;
  4. 净度:最不重要的一个指标。因为内含物都比较小,肉眼基本上都看不到。我选择的 VS2;

除此之外,还有钻石的荧光,奶钻、咖钻、绿钻等。可以自己了解下,看是否能将接受。我选择的是完全无荧光的。

另外不要迷信参数,D和E,E和F,VS2还是VVS2,普通人基本上是看不出来的。并且加上上文提到的奸商行为,也不应该过分迷信参数。犹豫不决的时候,可以在店里让柜员掩盖标签,你觉得哪个好看就买哪个。:)

如何测量手寸

如果是和女朋友一起去珠宝店挑选钻石的话,就没有这个问题了,可以现场试戴。如果是选择裸钻网购,可以使用:

  1. 测量卡片,比如 BlueNile 提供的,免费申请即可;
  2. 使用绳子测量;
  3. 或者其他可以在淘宝购买的测量工具;
  4. 去店里找类似的款式试戴;
  5. 为了保险起见,还是推荐购买有调整手寸服务的珠宝商;

最后如果男士想要制造惊喜的话,再提供几个方案:

  1. 带她假装不经意间去珠宝店,然后免费记下合适的手寸;
  2. 在她睡觉的时候偷偷测量;
  3. 将她敲晕,然后测量(同事提供的方法,作者不付责任);

小贴士:

  1. 手再一天当中不是固定的手寸,比如傍晚会膨胀,早上会变细一些。拿到戒指不要一下子觉得不合适,最好试戴几天;
  2. Tiffany 的手寸基本都是 HK13,即美国的 6 号手寸,柜员的解释是,基本上每个女生的食指、无名指、中指,总有一个手指可以戴上 6 号;

说在最后的话…

说了这么多,其实开心最重要。选择一颗钻戒只是两个人即将一起度过下半生的众多选择中的一个,无论是裸钻还是品牌钻石,无论是选择什么品质,两个人默契,观念一致或者最终达成一致,才最重要。

最后我选择的钻戒信息如下,供网友参考:

实际到手的成品如下:

祝读者幸福!

 

玩了一下 Github 个人首页的 Profile (使用 Action 自动更新)

Github 最近推出了一个 Profile 功能,大体上就是用户层面的 Readme。如果你新建一个和你的用户名一样名字的仓库,这个仓库的 Readme 就会展示在你的个人主页上。

虽然仅仅是一 Markdown 形式的 Readme,但是可玩性也很多了。

比如有一个服务,将这个服务 URL 的参数改成用户名,就可以用一个图片显示个人的开源贡献信息等,原理和项目上的 badge 差不多。

还有展示自己的睡眠数据的:

还有展示年度进度的:

还有在主页交换链接的,并且把这些链接做成了很漂亮的卡片:

 

我一直很喜欢看维基百科的 Picture of the Day,甚至有一段时间写周报的时候,每周都会贴一张 Picture of the Day 的图片在周报的末尾。一个原因是这些图片都非常精美,是由一个小组挑选出来的,普通用户也可以贡献,你可以发现这个世界上还有这么漂亮的地方。另一个原因是阅读维基百科可以学到知识。

 

2020-01-02 的 POTD

所以我就做了一个每天更新 Picture of the Day 的 Github Profile。基本的原理就是使用 Github 的 Action 功能,每天跑一个脚本,去维基百科查到今天的 Picture 地址,然后更新 Readme 中 Picture  的 URL,这个 Readme 就会展示在我的首页上。

实现非常简单,所有的东西都在这个仓库里面。如果你想制作定时更新的 Profile, 可以参考一下这些脚本:https://github.com/laixintao/laixintao

有几个可以少走的弯路,分享一下:

  1. 让 Action 的机器人 push commit 是一个比较 tricky 的事情,好在可以直接用别人写好的 Action,这就是 Github Action 的设计精妙之处吧。像 checkout, setup-python 这种东西,都有现成的 Action 了,不同的用户之间可以组合 Action 实现自己的 CI。git push 使用的 Action 是这个:https://github.com/ad-m/github-push-action 使用方法可以参考这里,可以说非常简单,甚至 Github 的 Action 运行的时候默认就会设置环境变量 secrets.GITHUB_TOKEN,连你手动给机器人设置 Write 权限的 Token 都省去了。
  2. 使用 Action 更新 commit 是一种方法,应该也是简单的方法。一开始我是想用 clock.sh ,不需要 clone 下来仓库,直接使用 Github 的 API 去创建 block,然后创建 tree 和 commit,但是这样操作太复杂了,就放弃了。有想法的用户可以研究一下 Github 的这套 API
  3. 放弃了 clock.sh 的代价就是…… Github Action 的 schedule 功能感觉有 bug. 如果 workflow.yml 写的有问题,Github 不会告诉你哪里有问题,直接就不会运行,对于调试来说还是挺不方便的;使用 schedule 会有一些坑。比如一你开始写了一个 crontab 15 * * * * ,调来调去最后发现无论如何改都生效不了了。而且 Github 这边就是不运行,没有调试方法。比较直接的方法就是直接将 workflow 换一个名字,push 过去,这样相当于在 Github 那边新建了一个 workflow,重新 schedule. 所以遇到此类问题不要怀疑是不是你的 crontab 写错了,直接换一个 filename 吧。
  4. schedule 功能最短的运行时间是 5min 1次,所以写 * * * * * 是没有意义的;

最后,我发现维基百科有时候会更新出来很恶心的图片,比如今天的…… (恶心,慎点 https://en.wikipedia.org/wiki/Template:POTD/2020-10-08 )

 

对中台的一些想法

声明:本文仅代表个人想法,不代表我的雇主的想法,也不代表我的同事的想法。

一开始有人开始提出“中台”这个概念的时候,我对此是嗤之以鼻的,认为又一个的炒作的概念。对于中台,我的认识是,将一个垂直领域的东西做成一个 SaaS 平台,它的价值就是避免一定程度的重复建设。举个例子,比如一家公司的很多个 BU 都有播放客户的广告的业务,那么追踪广告的效果就是每一个 BU 做的事情。这个事情需要做 N 遍,但是如果将广告效果追踪变成一个 SaaS 服务,就不需要大家都去做一遍了,只要接入并使用这个服务就可以。这是我理解的中台,可能和其他人的理解有出入。即使在最初提出“中台”的那帮人里面,估计也有很多不同的理解吧。

总之,后来我的 title 也不知不觉地变成了中台开发工程师。这篇文章就讲讲我们走过的弯路吧。

我们做的中台叫做故障定位中台。出现这个“中台”也有一定的历史原因,我们公司很多 BU 都有做故障定位的 SRE,也就有很多故障定位系统。我们在中台想做的就是把这些故障定位系统给统一接入进来,复用一些能力。

至于具体的实现就不多说了,没有什么魔法,如果让你来实现,估计跟我们现在的样子也不会差太多。主要说一下我们做的不好的地方吧。

简单

对于一个需要其他系统接入的中台来说,我觉得最重要的东西就是简单。在一个垂直的领域做中台,不可避免的要引入一些新的,抽象的概念。但是引入概念越少越好。印象比较深的,红姐以前试图教我设计 DSL 的时候说过,先实现功能,然后看哪些东西是可以去掉的,最后剩下的就是 DSL. 我觉得非常对。只有简单,才能让出错的概率更小,接入的成本才会低,别人才会愿意用你的系统。中台最大的失败就是没有人使用。

先实现功能,然后看哪些东西是可以去掉的,最后剩下的就是 DSL.

——thautwarm

我觉得一个产品在不知道将什么作为自己的竞争力的时候,“简单”就是最好的竞争力。比如 clock.sh ,一个可以托管 cronjob 的平台,创建一个新的任务只需要填写 4 个值,你的 cronjob 就可以跑起来了。

没有保持简洁,就没有用户。没有用户,也就没有后面的故事了。

而我觉得踩过的最大的坑, 就是这里。有同事之前是做交易系统的,我感觉他们设计的东西都非常复杂。以我们的接入接口来说,入参有 20 个参数,返回值需要用户填 20 个参数,就太复杂了。每次新用户接入,我基本上要给他们培训 4 个小时的时间,后续配合调试的成本也巨大。

作为一个平台,至少要做到用户自己看文档就可以进行接入。不然每次接入都需要进行特殊的培训,显然是不具备通用性的。

度量指的是对于接口方需要让他们看到一个运行的状态,知道自己的东西运行了多少次,效果是什么。

度量与统计(管理)

大部分的中台会作为一个服务提供方让别人来接入吧。所以就有对接入能力管理的要求。对于我们的平台来说,这个管理的需求统计这些接入方运行了多少次,失败了多少次,运行的效果如何。

不同的平台对于统计和度量的需求也不是一样的,分情况具体对待吧。我们的情况更有一些棘手,就是很难通过程序来判断运行结果的正确性。这里有一个悖论,就是如果我们如果事先知道一个结果对不对,那么就相当于我们已经知道了“正确的答案”了,后面做的事情也就没有必要了。所以现阶段我们的度量还是基于人工的。

集成功能

中台一个核心的思想就是 1)减少重复劳动,将一些轮子一次性做好,其他人只要用就可以了 2)结合一些已经有的系统,发挥1+1 > 2 的效果。

所以对于一些常用的操作,可以封装成 SDK。这句话说起来很简单,门槛也很低,谁都可以写。但是实际做的好不简单。可惜的是,很多喜欢写 PPT 的人认为“写代码是最简单的事情,是没有技术含量的事情,是谁都可以做的事情”。我见过的大多数的 SDK 都乱七八糟,一通乱写。

要注意一个点是,尽量地少抽象新的概念,如果没有必要,不要增加实体。尽可能地减少框架对用户的束缚。尽量让自己提供的东西成为一种“选择”,而不是一种“约束”。

说到这里,我又佩服 prompt-toolkit 写成了一个库,而不是一个框架。框架是它来调用你写的 API,就增加了很多的限制。而库是你去调用它的 API. 举个例子,从上手成本上说,一个库你可以看一下函数声明就上手开始用了,对于一个框架,你要知道它是怎么运行的,它是怎么调用你的代码的。