人生有台阶

person stepping on blue stairs

法不轻传为什么 2022 年了,依然让堂弟入 IT 的坑当中,我其实提到过,我希望堂弟能够走 IT 的路线,从而摆脱黄土朝天的现状和未来。

但说实话,如今我觉得,我可能过于高估了自己,以及低估了阶级之间的代差。

我父亲是从村里走出来的学生,到城里上学,并考入了公务员。而我如今能够成为一个软件工程师,很大程度上得益于从小学习 IT。大伯则是一直留在村里,虽然中间做生意、搞绵羊养殖,但总的来说,都是做的和土地相关的事情,堂弟也从小耳濡目染,给大伯帮忙。

对于我来说,我站在一个更高的起点上,从而走出了自己的路。堂弟的起点更低,我的路线未必适合他。甚至我的选择可能就是一个错误的选择,他需要走的,是曾经我父亲的路,从村里到城里,再从城里到更好的城市里去。

优秀的人当然可以跨越这个步步前进的设定,但终归只是少数人。

想起来之前知乎上的一个段子 —— 凭什么别人几代人的努力,被你努力一下自就给超越了?

法不轻传

a man and woman holding a skateboard

表弟跟我学了半年的编程了,进展不多,所以开始有些畏难心理。

作为堂兄,我是希望他能够有所成,奈何基础确实差距比较大,没有成果也实属正常。

回过头来思考这半年的问题,我觉得最大的点在于 —— 我没管住我自己。

教堂弟一个他自己可能并不是很喜欢的东西。喜欢是一切成就的源泉,只有喜欢,才能做到极致,但堂弟并不喜欢,所以在这个事情上投入难免不足。而投入不足,也就更难有所成就,形成了负向的飞轮。

而我在其中,则扮演了一个替他做决策的人,实际上,能够做决策的人只有他自己。他需要找到自己真正喜欢的东西,然后从这个喜欢出发,发展出自己的事业。

😮‍💨

学而不思则罔?学而不用则罔

love to learn pencil signage on wall near walking man

在论语当中,有一句非常经典的句子 ——

学而不思则罔,思而不学则殆

孔子,《论语 · 为政》

我们从小就学习这句话,它也伴随我们走过了我们的学习生涯。但直到最近,我才更加深刻的理解和感悟这句话,并将其进一步拓展 —— 学而不用则罔

在学校学习的时候,我们学习的往往是理论知识,无需专门的去实践,所以就如同孔夫子所言,我们只需要学习并思考,便可将知识融入到我们脑海中,成为我们自己的知识和智慧。

而当我们走上社会之后,我们的学习则更加的功利 —— 你不太会去学习一些纯理论的,你所学习的东西,往往是需要解决一个现实存在的问题。因此,我们需要将「学而不思则罔」改一改,变成「学而不用则罔」。

学然后致用,才能让我们不至于迷失在不同的理论当中,相互冲突。实践不同的理论,并因此来改变自己的生活。

工程师,除了互联网,还有很多选择

orange camping tent near green trees

2022 年景不好,看到不少裁员的,也看到不少人面对裁员显得悲观,甚至也看到有些人提到「如果不做成管理层,感觉这一生可以看到尽头」。

但工程师其实还有很多选择 — 这世界并不是只有互联网公司才需要工程师,任何一个和数字化强相关的企业,也都需要工程师。大部分时候,如果你放弃了高薪,你其实完全可以找到一个可以轻松做到 Work Life Balance 的工作,他们可能偶尔加班,但绝对不卷。你每天可以接送孩子,周末可以出去玩,而不是每到周末就整个人被榨干,没有力气。

我们现在面临的社会是一个阶级逐渐固化的时代,你其实希望通过在互联网大厂实现的是阶级越迁。但时间窗口已经消失,已经不存在阶级越迁的可能性了,你还会选择继续在互联网大厂卷么?

既然上升无望,不如好好过你的生活,静待下一个周期。

《李诞脱口秀工作手册》书摘

d2b5ca33bd970f64a6301fa75ae2eb22 41
  • 每天睡觉前唯一要考察的只有一件事:你有没有持续地变好?今天是否获得了一点昨天没有的东西?这是查理·芒格的建议,事实上我看很多优秀的人在读到这个建议前就是这么做的。
  • 人生的目的就是成为更好的自己。
  • 节奏,就是先同步,再引领,然后无限循环。 “先同步再引领”是我在一本教说服力的书上看到的说法,这里借用来探讨节奏,与原义有些不同。
  • 刚进入职场,只要是符合道德不违法,什么活钱多干什么活。刚毕业,刚实习的时候,不要想那么多,就是哪个公司大就进哪个公司,哪儿给钱多去哪儿干。这个市场还是非常客观诚实的,你是不会得到超过你能力范围之外的钱的。但是你干了一段时间呢,就不能再用这个原则处理自己的职业规划了,尤其是面对迷茫空虚的时候,每个人不一样,刚才说的是比较幸福的情况,有的选。如果你处于一个被选择的状态,那能做的也不多了。
  • 学习一流,模仿二流,成为三流。如果能成为三流,就已经能活得很好了。
  • 我经常劝年轻的朋友,尤其实习生的一句话就是:不要那么焦虑,公司是不会把特别重要的任务交给你的。你是谁,你会什么,公司怎么可能会把重要的事情交给你。不要害怕,你的上级把任务交给你的时候,预期就是你会搞砸。你为什么觉得他会把一个不能搞砸的事情交给你呢。如果真的是这样的话,你就赶紧离开,一个靠谱的领导是不会这样的。

《病人家属,请来一下》书摘

d2b5ca33bd970f64a6301fa75ae2eb22 40
d2b5ca33bd970f64a6301fa75ae2eb22 40

生命,就是由一系列意外组成 ——与一名癌症病人女儿的书信往来

  • 正是因为有了这样的时间和空间的限制,每一天的鸟语花香才显得弥足珍贵。
  • 选择大教授仍然是一个稳妥的做法。也许你认为看诊一分钟要解决的是自己心中的疑问,但对教授来说,是要决定治疗方案的,任何无关的信息都会拖延他下判断的时间,作为门诊医生,他并不希望和你展开聊天。高等级的医院里,下面的医生执行医疗方案是没有什么问题的,这一点不需要过于担心。
  • 医生的说法也许有不同,这也是合理的,这说明目前你父亲的状态,治疗的选择很多,没有一个确定的最优解,这本身就是生命的奇妙之处。

第一章 医疗信息篇 明确思路,谋求共识

  • 大量数据表明,厨房油烟也许才是女性患肺癌的重要原因

第五节 别总让医生管理你,你也要管理好医生

  • 有时候你也不得不承认,即使程序是正义的,民主也必定是无能且低效的。

第二章 心态篇 癌症没有想象中那么可怕

  • 谁出钱,谁知情。

第五节 人是种需要集体支持的社会动物

  • 千万不要小看这种感觉。当人在对“生存”本身没有安全感的时候,要获得内心充盈、自如的状态,是非常难的

第二节 女婿经济学:癌症病人家庭如何决定花多少钱看病?

  • 女婿和媳妇没有本质区别,也和男女无关,关键是这个家庭当中谁能够获得大多数家庭成员的信任,进行合理的决策

第三节 医生总让我选择治疗方案,太纠结了怎么办

  • 人总是在出现不如意结果的时候开始质疑自己当初的选择,但你问问自己,当时做的选择是不是基于当时的情况的最优解。如果是的话,要努力放过自己。
  • 开个家庭会议。叫上负担家庭收入主要来源的人、对家庭的债务和风险负主要责任的人、药费的主要提供者、家里话语权最大的大家长,坐在一起开一次家庭会议。你不妨用这样一个公式来帮助你判断。用药程度=药物效果-并发症-价格-家庭负债例如这个药物 100%有效,就是 100 分;并发症的发生率是 10%,就是 10 分;价格是每年 20 万,要用 2 年,那就是 40 分;家庭负债是 80 万,就是 80 分;用药程度=100-10-40-80=-30 分。低于 0 分,意味着从你们家庭长期发展的角度考虑,眼下这个矛盾也许不适合投资这么一大笔钱解决。会议的召开和结果,都要和其他家庭成员同步。

第五节 买对保险不踩坑,你才能逆风翻盘

  • 所以我一直认为,代理人是短期内不能完全被互联网取代的存在,他不只是一个中介,他更应该是一个优质的法律顾问

《武汉女孩阿念日记》书摘

d2b5ca33bd970f64a6301fa75ae2eb22 39

在 2023 年,奥密克戎疫情袭来,我国疫情防控从之前的严防严控调整为逐步放开的时刻,这本书值得你去读一读,去感受一下 2020 年初武汉人民的绝望和痛苦。时至今日,我们所遭遇的病毒可能和当时已经完全不同,但我们依然需要珍惜身边的人,为自己身边的人做好准备,应对疫情。

白宦成
d2b5ca33bd970f64a6301fa75ae2eb22 39

来到火神山,见到外婆 2月19日 星期三

  • 新冠肺炎是一个让人孤独的疾病,把每个人的路分开。走着走着你会发现,旁边是没有别人的,只有你在踽踽独行,前方可能有野兽,可能有泥泞,而你没有地图和向导,一切都需要自己去摸索
  • 我一直觉得,“骄纵”必是先有“纵”而后才“骄”,而过分“懂事”除去个人修养,有一部分原因是自卑,担心自己不那么被在乎,所以往往主动向后退一步,选择对生活妥协。

“你要是照顾不好外婆,我对你不客气” 2月21日 星期五

  • 不知道其他人是否也有像外婆这样倔强又不会撒娇的长辈,喜欢用责怪去表达关心。大概亲人总是这样,好话总要反着说,我们需要抛开情绪的因素,体会对方说话的本心。

回家之后

  • 以前好朋友对我说过一句话,成年人应有的礼貌,是把自己的伤口舔好再出来见人。大概像某种昆虫吧,难过的时候把痛苦织成茧,包裹着自己,待有朝一日恢复后,再优雅地破茧而出以新形象见人。

35 岁问题,只与你的竞争力有关

man and woman sitting on bench

时常会在各种论坛看到一些关于 35 岁裁员的话题,大家都很恐慌自己会在 35 岁被裁员。

但说实话,这个事情其实没有那么复杂,你是否 35 岁被裁员,只与你的竞争力有关

当然, 不同的人和环境竞争力和年龄的相关性是有区别的:

以绝大多数人感知到 35 岁裁员的消费互联网为例:消费互联网主要需要的是快速迭代的能力和对于用户行为、用户需求的感知,这里需要的更多是随机应变的能力,自然也就更多需要加班、卷。当然,你也可以通过一些别的手段来增强自己的竞争力 —— 比如质量、效果。并不是快就是绝对的好,快但是在错误的方向蒙眼狂奔,也是一种悲哀。

而对于传统的To B 的行业软件领域,虽然可能增长没有那么快,但由于需求明确、变化少,更多是自己在行业当中的经验的产品化,则不需要那么快的迭代速度 —— 毕竟你的用户不会迭代那么快。在这样的行业当中,你待的时间越久,积累的行业 Know How 越多,自然竞争力也就越强。

选择一个适合你的领域,提升自己在领域的竞争力,才是无惧 35 岁裁员的唯一手段。

一个支持 ES3 环境的 querystring

text

相比于使用 Uniapp / Taro 之类的,我其实更喜欢使用小程序的原生来进行开发。主要是减少中间商赚差价,性能损耗更少一些。当然,也少了不少好用的体验 —— 比如随便引入 NPM 包,好在是现在的小程序开发者工具也提供了 NPM 构建的能力,所以一些基本的使用是没有问题的。

不过,小程序本身环境的特殊性,我在使用 NPM 包的时候还是会有一些谨慎的 —— 要选择尽可能小的、不受平台依赖的包,来缩小小程序的包。所以当我发现一个可以在小程序中使用的包的时候,我就会将其写下来, 以备不时之需。

在涉及到 Web 开发时,一个比较常见的场景是构建 HTTP 中的 QueryString,以便在发送 GET 请求时传递参数。但自己手拼参数还是比较痛苦的,所以用一些 package ,可以有效的提升开发的体验。

TL;DR

你可以在小程序环境中使用 <a href="https://www.npmjs.com/package/querystring-es3">querystring-es3</a> 来进行 querystring 的构建,包的体积不大,可以达到比较好的效果。

const { encode } = require('querystring-es3')

encode({
  page:1,
  pageSize: 10
})
// return 'page=1&pageSize=10'
Code language: JavaScript (javascript)

为什么不是 qs

querystring 的处理包当中,比较出名的除了 node 内置的 querystring 之外,应该就是 qs 了,但实际在使用过程中,小程序的静态分析依赖了 qs,导致开发者使用时要么关闭提醒,要么换包。考虑到我还是希望使用小程序的静态分析,所以就只能替换包了。

待解决问题

  • 实际上我使用 querystring-es3 主要是看到他写的 ES3 compat,但可能其实我可以直接用 query-string ? 需要验证一下。

用小米电视看电影,感觉挺好

flat screen TV

去年买了小米的电视,但一直都闲置在那里,没怎么看。毕竟对于我来说,电脑是一个更加高频度使用的设备,完全没有怎么看过电视。

但过去一年里,没有什么文娱活动,更多都是刷抖音,刷信息流,时间被大量的消耗。在跨年的时候,突发奇想,我是不是可以把电视抱到卧室,在睡前看看电影啥的,毕竟我一直想看电影,但说实话,疫情的原因,让人不太敢和别人在一个密闭空间待两个小时。

说干就干,我把电视抱到卧室,开始用小米电视看电影。

4d2dbe4e85752e901e7446f4570ff4ea
临时搭的架子来看电视

配置好之后,两三天里,我看了好几部之前想看,但没有看的电影 —— 《十万个冷笑话》、《坏蛋联盟》、《小黄人大眼萌 2 :神偷奶爸前传》。

目前我觉得比较好的有:

  1. 我买了小米的电视会员,可以免费看很多电影,这个我很喜欢。虽然部分的影片是需要付费的,但绝大多数是可以免费看。
  2. 更新的很快:小米的影视库资料还行,我想看到的基本都有

不太好的点

  1. 之前我买电视的时候,没怎么花钱,甚至还不如我在用的显示器贵,所以画质很一般、也很容易卡。后续买电视还是要买个更好的品质的。
  2. 无线的网络不太行:毕竟租房,不太好接线,所以看高清的视频就会容易卡,以后自己买房的时候,还是要接网线。

结合小米的广告的尿性,我感觉后续我的最好的方案是一个比较好的传统电视 + 一个电视盒子,这样体验会好点。 Apple TV 买起来!

学会用巧劲,做选择

d2b5ca33bd970f64a6301fa75ae2eb22 3

如果说,一个人最重要的是什么,那便是判断力。有了判断力,做事便有了轻重缓急,有了不同的资源调配。

d2b5ca33bd970f64a6301fa75ae2eb22 3

大部分人终其一生,不做选择,而是随大流,别人做什么,我也做什么。这样带来的结果是终其一生,如浮萍跟随时代和他人的步伐,飘摇不定。

想要摆脱这种不确定性,拥抱确定性,则需要学会做出选择,做那些重要的事情,达成自己的目标。

技术文章格式

MacBook Pro near white open book

在查看一些技术文章的时候,看到一个不错的技术文章的范式,记录一下,这样后续我的技术文章也可以写的更有价值一些,而不仅仅是一个笔记。

以下内容为对应的范式和我的批注。

结构

  1. 简要的 Intro:介绍你在做什么、遇到了什么问题。
  2. tl;dr :总有人不想看长文,对他们友好一些
  3. 目标 + 结果:明确目标既可以帮你明确写作的目标,也可以框定问题的范围
  4. Shortcuts taken :可以快速带走的 intro,也可以理解为是 tldr 的内容
  5. 发现问题、解决问题的过程
  6. 结果
  7. 待解决的问题:在这个过程中你可能会有很多的新问题,可以记录下来,以后慢慢研究

2022 年 12 月月度总结

summary

今年的最后一个月,到了尘埃落定的时刻,也到了一年的总结时刻。今年的一年,是毫无收获,躺平的一年。。。

Objective 1:持续获取现金流,并构建未来收益的现金牛

KR1:投资收益达到 20000 元

12月市场开始回暖,我的基金也开始回暖。终于算是回归了本金。今年的投资收益非常的惨淡,一方面有市场的因素,另一方面,我认为我的 KR 本身有问题。这个到年终总结再讨论吧。

KR2 :单篇稿费突破 6000 元

无变化

KR3 :达成年度预算,支出不超预算

没出门, 也就没超预算。不过这个月有一些紧急支出(指阳了以后,买了大量的储备物资,现在还没吃完。。)

KR4 :构建软件类现金牛业务,预期产生收益 10000 元人民币

暂无进展

Objective 2:提升生活基础设施,构建未来生活好基础

KR1:前往 6 个城市旅行

这个月没有出去玩。。

KR2:进行 20 次文娱活动

没有进行文娱活动。

KR3:借助智能化设备,缩减在家务相关事务上耗费的时间

这个月没有啥变化。

Objective 3 :开拓视野,打造多元行业人才

KR1:写 15 篇书评

暂无进展

KR2:输出关于 API 的 Newsletter 12 封

12月份起草了两篇文章的大纲,但没有写成正式的文章。

KR3 :完成计划中的三本图书的写作

暂无进展。

几个 Swagger UI 的替代品

black and silver laptop computer

Swagger 算是 Code 2 Doc 的默认选项了,各种语言都提供了生成工具,此外官方还提供了一套方便使用的默认 GUI。

d2b5ca33bd970f64a6301fa75ae2eb22 36

不过,Swagger UI 本身其实并不够好用,所以社区就会提供一些 Swagger UI 的替代品,方便大家使用。

ReDoc

ReDoc 是一个前端的开源项目,在 Github 上拥有超过 1W + 的 Star。对我来说,我觉得他最好的点是左中右三栏模式,左侧切换 API,中间查看 API 详情,右侧查看接口调用的 Sample,比 Swagger 官方的 UI 瀑布式的要舒服。

d2b5ca33bd970f64a6301fa75ae2eb22 37

Angular Swagger UI

Angular Swagger UI 同样是一个开源的项目,界面简洁明了,虽然是瀑布式布局,但由于在界面上更加简洁,所以同样可以在同样的屏幕中,获取到更多的信息。

d2b5ca33bd970f64a6301fa75ae2eb22 38

使用 Taro 的一些小配置

text

我自己在使用 Taro 开发小程序的时候,一定会开启的两个配置:

1. 开启压缩

Taro 在预览模式生成的文档比较大,对于小程序的预览来说,不是很友好,所以开发的时候,我经常会打开压缩,以便于在小程序开发者工具进行预览。

修改也比较简单,只需要在你的 package.json 当中加入对应的环境变量 NODE_ENV=production 来支持即可。

diff 见下

d2b5ca33bd970f64a6301fa75ae2eb22 34

2. 开启 webpack 持久化缓存

Taro 可以开启 webpack 的持久化缓存,以便加速 webpack 的构建速度,因此我也会开启这个配置,以提升构建的速度。

d2b5ca33bd970f64a6301fa75ae2eb22 35

《小镇金融学》书摘

d2b5ca33bd970f64a6301fa75ae2eb22 33

Comments

这本书总体和之前看到过什么小岛经济学之类的风格很像,虚构一个环境,并在这个环境中演绎金融学,可以读一读,对于我们所熟悉的金融机构有一些了解。内容总体来说比较薄。

第1章 画中蓬莱

  • 请不要憎恨贪婪与恐惧,恐惧和贪婪是金融市场的永动机,波动的成因无一不是贪婪和恐惧。金融市场以贪婪而始、以恐惧而终,在繁荣与萧条中往复循环。金融市场的魅力恰恰就在于此,没有波动的市场又有什么意义呢

远方即财富

  • 贸易是人类历史上所有重大创新的原动力,有分工才会有贸易,有专业化才会有贸易,贸易确实没有创造什么,但贸易本身就是一种重大的创新。商品从一个人手中流转到另一个人手中,就是因为自己创造不出来(或者创造不划算)。

银钱之行,故曰“银行”

  • “模糊面纱”原则又称“无知之幕”,只有当缔约各方都对未来无知状态时制定的游戏规则才合乎公平。在小镇的故事里,没有人知道未来会是怎样的,只有以最公平的手段保护和惩罚所有人才能确保自己最大限度得到保护,虽然结果不一定公平,但过程肯定公正。

第3章 金融的本性

  • 供给会自行创造需求,这是萨伊定律的结论。

卿本佳人:房地产的金融属性

  • 看着若有所思的轩辕启恒,长孙东阳长叹了一声:“三生三世枕上书,可对现世来说还是那句话,最重要的永远是当下,这才是‘理性’本质,才是俗人的本心。”
  • 一般来说,只要一种商品可以短时间内暴涨(学名“做多”),就具备了最基本的金融属性。在这里我们暂时不考虑暴跌的情况,在金融理论中确实有个名词叫“做空”,也就是赌价格下跌。微观层面确实有人通过“做空”盈利,危机爆发也是因为有人故意“做空”,但这些都是建立在已经有人“做多”(赌价格上涨)的基础上。实际上,宏观层面的“做空”是一个伪概念,打压价格不可能吸引全民投身炒作,毕竟绝大多数人都通过价格上涨才能获利

第5章 走出洪荒

  • 商业银行最基本的原理非常简单,便宜借储户的钱,以更高的价格借给贷款者,金钱高买低卖的商业版本罢了

回不去的从前

  • 通常情况下买房的资金杠杆比率为1∶3—1∶5,也就是说,房价只需要上涨10%,投资者就能赚取30—50%的收益。同样的资金量投入,杠杆可以成倍扩大收益率,当然,也会成倍扩大损失。投资者没有不贪婪的,这是人的本性之一,所以,房地产将永远是投机者的天堂,昨天是,今天是,明天也是

盛衰循环的辩论

  • 经济繁荣的根本原因是大创新,不是货币扩张;同理,经济萧条的根本原因是创新带来的刺激衰减,不是货币收缩,从繁荣到危机不过是将整个过程以金融的方式记录下来罢了。
  • 改变世界的创新在当代经济学中被称为“毁灭型创新”,所谓“毁灭”必定是开天辟地,以新产业毁灭旧产业。新产业必然创造巨大的利润,并对应融资方式的改变,也就是金融革命配合产业革命。金融革命一旦出现,人们便能轻易获得资金,其后模仿者蜂拥而至,投资新产业、投资新产品……“毁灭型创新”注定改变了人类社会生活,工业革命、电气革命、信息技术无不如此。
  • 任何一次“毁灭型创新”都有相似的历程,创新开始的时候会生产奢侈品,随着创新延续成本逐渐降低,普及到草根大众的时候,创新使命就基本结束了

投资银行:人类第二次资金大融合

  • 只有能赚钱的技术才是真正的好技术,也只有实现商业化才能普惠于万众生灵
  • 在金融市场上,如果大家都这么认为,那这件事就一定会发生,这就是所谓的“预期自我强化”
  • 人类第二次资金大融合实现了产业链中的资金流动,造就了投资银行,也对美国经济转型与发展起到了巨大的推动作用。当时投资银行主导的并购中,目标企业拥有互补性资源,注重研发和创新,着力整合各方资源。一旦在大部分行业完成了上下游企业并购,美国工业结构便出现了永久性的变化,国民经济集中化程度空前提高,伴随而来的则是规模效益和垄断利润

再造辉煌

  • 一切的关键,是创新。一次“毁灭型创新”代表着出现一个新的产业,新的产业又代表着形成一个全新的利益格局、一个创新者主导的利益格局。打破一个旧世界,建设一个新世界!旧有利益格局一旦被打破,创新者就会成为新世界的主宰。在创新的路径中,银钱业始终为创新提供了充足的燃料——钱,资本从一个天才转向另一个天才,从一个产业转向另一个产业。只要能在经济分工中掌握最核心的创新,就一定能找到世界上最强大的资金,资金每日梦想着寻找更高的报酬

开发者文档的三种内容层次:字典、概览和教程

APILetter

不知道,你有没有关注过开发者文档的信息结构。下图是 Google Docs 的 API 文档。

89ug0i

在菜单中 Google Docs 提供了 Home、Guides、Reference、Samples、Support。你有没有想过,这些内容为什么如何设计?在我看来,这是开发者文档内容的三种层次。

第一层:解决有没有的问题

典型代表:API Reference

绝大多数开放平台也好,To Developer 产品也罢,首先要解决的问题是让开发者知道我有什么样的能力。而最简单、最直接最高效的方式,便是 API Reference。

各大产品在进行对外开放时,首先准备的便是一套 API Reference。在 API Reference 当中,你可以看到开发者应该如何调用一个 API;某个 API 的入参是什么、出参是什么;如果出现了失败,应该如何处理这些错误。

当一个 API Reference 为开发者提供了简洁、明确、易懂的文档内容之后,开发者基本就可以准备开始进入开发流程了。

Opinionated Notes:RESTFul API 的 API Reference 理论上不应该存在多层级的资源关系。

优秀的 API Reference 参考:

第二层:解决怎么用的问题

典型代表:API Overview、单个业务领域的 API Guides & API Tutorial

作为开放平台,当完成了 API Reference 之后,便算是及格了。但及格不应该是目标,目标应当是卓越。抵达卓越,则需要更多内容的帮助。

API Reference 回答了「能用什么」的问题,但没有解决「如何使用 API」的问题,特别是复杂的业务场景下,同一个业务内可能会需要多个不同的资源来进行 API 的操作,这个时候,如何使用这些资源,并将这些资源包装、关联起来,就成为极具业务属性的 Know How 知识。

举个例子来说,以服务端 OpenAPI 为例,日历的资源就涉及到用户、日历、日程、会议室、参会人、权限管控等多个不同的资源,如何串联这些 API 才能达成你的业务目标,就成为一个非常重要的说明。对于日历的能力熟悉的开发者可能很快就可以找到调通的方式,但对于不够熟悉的,这些 API 之间的串联,可能需要他花费一天,甚至一周的时间才能真正理解背后的含义。如果想要降低开发者调通过个 API 的时间,那么介绍这些不同 API 之间的关系,其在业务系统之中的含义就尤为重要。

如果你对于服务端的 API 感触不深,那么客户端的 API 可能会让你感受更加深刻,以微信小程序的中的蓝牙设备开发为例,如果你作为一个从未开发过蓝牙能力的开发者,看到了蓝牙提供的这一系列 API,只怕马上头皮发麻,需要每一个都看一遍才能理解其含义和价值;在蓝牙这件事上阻塞个半周一周也是常态。

d2b5ca33bd970f64a6301fa75ae2eb22 31

一个好的 API Guide / Tutorial 可以有效的降低开发者在调试这些 API 过程中所耗费的时间。当然,微信也意识到了这个问题,提供了一套非常好的 API 说明

优秀的 Tutorials 参考

第三层:解决场景化使用的问题

典型案例:Code Sample,Demo App,场景化的使用教程

API Tutorials 可以解决的是面向场景化的单个领域的内容。它帮助开发者很好的解决了一个领域内的产品能力的串联。但在实际的业务场景当中,开发者面对的不是已经拆解到 API 粒度的任务,而是面向场景设计的不同问题。对于开发者来说,把场景拆分成 X 个 API 并没那么容易(特别是如果经验不足的时候),因此,一套标准的 Code Sample ,甚至是 Demo App ,都可以帮助开发者快速解决面向场景化的问题。它可能涉及到了客户端、服务端,或者是面向了多个不同的领域。这些内容帮助开发者可以快速 landing。

以飞书开放平台为例,飞书开放平台在开发教程里提供了多个领域、不同方向的场景化教程(虽然还不够多,远远不够),帮助开发者快速完成某个特定领域的功能的开发。

d2b5ca33bd970f64a6301fa75ae2eb22 32

这些内容可能未必能完全满足开发者的需求,但确实可以给开发者一定的借鉴意义,帮助开发者理解整个业务流程和对应场景下的具体的实现,帮助开发者快速完成业务需求。

第三层之后,应该是什么?

前面三层解决了有什么、怎么用的问题,而在整个应用的生命周期当中,怎么用并不是终极问题。下一步需要解决的是如何用好的问题。不过这个问题不在本次阐述的内容当中,所以我们留一个悬念,下次再说。

 衡量 API 设计质量的指标 — TTFC/TTFHW

APILetter

任何一个开放平台类产品,要解决的问题都是如何在现有的平台能力之上,开放一些能力给到第三方开发者,帮助第三方开发者开发应用,拓展体验,如果我们可以降低开发者在完成开放能力接入所需的时间,我们就可以让开发者有更多的时间去构建属于自己的业务逻辑,拓展平台之上的应用生态和开发者体验。

API 的设计质量、文档质量和错误处理信息的质量可以非常明显的影响到 API 的使用体验。但这些体验却很难通过我们在软件工程领域所使用的各种性能指标来衡量。我们可以通过一些专业的、对于 API 有判断能力的人来完成对于 API 质量的评估和优化的引导,但这件事并不利于持续发展和长期迭代。我们需要一个靠谱的指标,来引导我们持续性的、规模化的进行 API 本身的优化和迭代。

上图为 readme.com 提供的 TTFC 介绍

在这个问题上,Slack 给出了自己的答案 —— Time to First Hello World(TTFHW), API 服务提供商 readme.com 则提出了一个类似的概念 Time to First Call(TTFC)。

TTFC/TTFHW 为什么是一个好的指标?

在 TTFC 之前,我相信你或多或少都试过对自己的 API 进行统计和分析。你可能会基于技术工程指标来判断 API 的好与坏;进一步则会通过一些反馈的能力来完成(比如划词反馈、点赞点踩反馈)数据的收集和进一步的分析,你可能会将这些数据进行加权分析,从而得出一个质量评分,用于判断一个 API 的好与坏。

表面上来看,他可以帮助你发现你的 API 当中的不好的点,你可以基于开发者的反馈来快速对 API 当中的一些问题来进行修复,从而提升开发者的开发体验。但这个指标的一个缺点是:它是一个负向反馈的指标。作为 API 的提供者,你拿到这些反馈的时候,它可能已经早已影响了你的大多数开发者,甚至早已令你的开发者十分不快而你却从不知道。不仅如此,如果你的开发者们并不喜欢反馈,你的 API 的问题可能永远都不会暴露出来。

TTFC/TTFHW 如其名所述,记录的是一个开发者第一次调用所需要时长,你可以根据你自己的需要,来设定开发者行为的起点。而终点,则是开发者成功发起一次调用。

相比于需要开发者主动反馈所进行的数据收集,TTFC/TTFHW 的指标不需要开发者做什么,我们可以通过一些技术手段来完成这些信息的收集,从而在第一天开始收集数据。你不需要等自己的 API 有很多开发者之后才能开始进行数据的收集和反馈,只要设计合适的埋点,从 Day 1 就可以获取数据,并基于数据来分析指标和下一步优化的方案。

如何建设 TTFC/TTFHW

TTFC 和 TTFHW 的指标在实际的建设过程中并不容易。其中最大的问题是如何将开发者的行为和实际的调用进行关联。如果你的 API 在前端就可以发生调用,且能够在前端直接调用,还算是简单,可以通过简单的前端埋点来完成数据的建设,并配合开发者在网站上行为的埋点,来分析出具体的 TTFC / TTFHW。

而对于一些服务端的 API,则需要花费更多的心力来建立这些数据,你可能需要将开发者在网站上的行为和其对应的在 API 上的行为进行串联,从而形成一个完整的开发者图景。在最理想的情况下,你的统计系统和你的 API 网关系统上是可以打通的,你可以非常简单的将开发者在网站上的行为与发生在 API 网关系统上的行为进行串联,从而形成一整个从开发者进入网站到开发者了解 API 设计再到开发者真实发生 API 调用当中来完成。

不过,这件事在某些支持以应用身份来调用 API 的开放平台当中来说,就是比较困难的了。因为发生调用的最小单位是应用,而不是某一个人。但也并非绝对无解,你同样可以基于某些指标来圈选一部分开发者,并将这些开发者和实际网关当中产生调用的接口进行串联分析,得出开发者的实际的调用时长。

如何使用 TTFC / TTFHW

当你通过艰辛的数据埋点、数据收集、数据入仓之后,便可以进行数据分析,使用这些数据了。这里分享两个使用这些数据的思路,供你参考。

TTFC/TTFHW 的数据可以从整体数据视角和局部数据视角查看。

当你作为整体数据来查看时,你所拿到的是一个开发者完成整体调用所需的时长。你可以基于开发者的行为,来计算出开发者的 TTFC 所需的时长,和他进入到转化漏斗当中下一步所需的时间,并分析不同时长人群在实际转化率上的差异值,对比这些差异值,并得出判断和下一步的 Action ,优化你的 API 产品的实际体验,提升产品转化率。

上图为 moesif 提供的 TTFC 转化分析图表

当你作为局部数据来查看时,你可以将 TTFC/TTFHW 拆分成若干个不同的阶段,比如网站访问、查找文档、了解鉴权信息、阅读 API 文档、实际发生调用等多个阶段,并对这几个部分的耗时进行分析,从而得出一些定向优化的 Action ,来优化整个网站和 API 的质量,帮助开发者降低调用所需耗费的时长。

建设 TTFC / TTFHW 数据指标的一些建议

在建设 TTFC / TTFHW 的过程中,如果你遇到了困难,不妨试试如下的方式:

  1. 为你的服务端 API 提供一套在线的调试工具,从而让开发者可以在看文档的时候直接调用接口,测试效果。
  2. 如果你的 API 支持以开发者的身份调用,可以试着使用 OAuth 协议,让开发者在看文档的时候直接授权发起调用,并在调用成功之后给出相应的代码的生成。

一个可互动(Interactive)的文档,可以帮助你有效的降低 TTFC/TTFHW。

当然,除了产品本身的优化,你还可以试着提供更多的开发者教程、示例代码,来降低开发者调用你所提供的 API 的难度,优化开发者的体验。