分类目录归档:随笔

灵光一闪

灵感: Agora RTC/RTM 调试工具

我最近在写一些 Agora 的 RTC/ RTM 应用的教程,在开发 Demo 过程中,发现调试 Agora 的应用比较复杂,其实可以有一些辅助工具来帮助开发者更好的开发这些应用。

核心诉求

可以更加简单的调试 Agora SDK 当中的 Event

形态

  1. 独立的 Vue Componet / React Component
  2. 基于浏览器的 DevTools

基本功能

  • 支持触发事件(应该是一列 按钮,用户点击后,就会触发对应的事件)
  • 支持发送信息(应该是一个文本框 + 一个提交按钮)
    • 支持设定 Template
  • 支持查看频道内已有信息(最好还可以有筛选,这样方便只看自己关注的信息)
  • 支持查看 Client、Track等基本信息(如当前人数、当前用户列表等等)

为什么一定是独立的 Client?

在实际开发时,业务的逻辑和实际使用到的功能可能是需要多个步骤才能触达的。此外,根据应用的特性,还可能会有浏览器锁定、设备锁定等业务能力。这些能力虽然与 Agora 无关,但会影响调试时的难度,因此,有一个单独的 Client 可以用来调试 Agora 是一个不错的选择。

为什么最好是 Component / Devtools ?

在实际的开发过程中,我们可能会用到 Agora 的 Token 机制,借助这个机制,我们可以对我们的音频/视频 Channel 设定准入门槛,降低成本。但相应的,调试起来比较麻烦。

如果是 Component / Devtools ,可以通过传入 Props / 环境变量来完成 AppID 和 Token 的设定,降低调试的成本。

yellow Volkswagen van on road

一种低成本的旅行方式

今天这篇文章是我大学时喜欢的旅行方式,今天也分享出来,希望能够帮助到刚刚毕业的大学生。

你们可能面临了一个困难的开局,但困难的开局也意味着你们可以有更多的时间来锻炼自己。在这个既然努力也不一定能找到好工作的时候,不妨走出去看一看世界,思考一下人生。

我的旅行方式总结下来就是一句话:用时间换金钱

大学生的问题是比较穷,没有太多的钱,所以一个比较好的方式是牺牲自己出行的时间,换取更低成本的旅行。

总结下来大概是两点:

1. 出行:选择 T/Z 等火车出行

火车出行是我低成本旅行的一个重要选择部分。如果你可以接受多花一些时间,T、Z 开头的列车可以以一个比较低成本把你送到千里之外。

d2b5ca33bd970f64a6301fa75ae2eb22 31
深圳东至武昌 Z/T列车

以深圳至武昌为例,你只需要支付 268 ,是同样的高铁票价格的一半。

d2b5ca33bd970f64a6301fa75ae2eb22 32
深圳北至武汉 G 列车

你失去的是时间,获得的是更低成本的出行。

2. 住:选择青旅进行住宿,低成本 & 可以认识新朋友

作为一个「社牛」,我是很喜欢住青旅的,因为你可以非常低成本的在这里睡一晚。此外,还可以和住青旅的其他人一起聊天、唠嗑,是一个不错的选择。

d2b5ca33bd970f64a6301fa75ae2eb22 33
西湖边,特价只需 49 一晚

缺陷就是你需要和别人一起住,但毕竟在学校也是住宿舍,出来住青旅也没有太多难以接受的点。

总结

人生当中我们会遭遇很多困难的时候。如果当下无法改变,不如试着去过一过不同的生活,在低成本的时候过这样的生活,比我们高成本时可以更好的过这样的生活。

a9612210e0aa48ef7576a8a4b19db262

构建自己的应急处理机制

生活当中,疫情当下,我们很容易会在生活中当中遭遇一些意外事故,这个时候,我们为自己构建一套应急处理系统,可以帮助我们快速走出困境。

看个例子

以「小区被封控,但家里没电了,手机也马上就要没电怎么办?」为例,

我们可以从这句话拆解出三个问题:

  1. 小区被封控,导致我不能如常处理问题。
  2. 家里没电,导致我没办法正常生活,也没办法给手机充电。
  3. 手机没电,这意味着我可能与外界断联,无法处理任何事情。

当我们拆解出问题后,我们要做的就是给这些事情排列出优先级,并按顺序解决:

上面这些问题当中,手机没电是最严重的,因为手机没电会导致我和外界失联,失去解决其他问题的可能性。

其次,比较严重的是家里没电。这个是影响了我后续生活质量的问题。

至于小区被封控,这是我不可控的因素,因此,不考虑解决它,而是试图在这个大背景下寻求解决方案。

而从优先级来看,我们则需要按顺序处理这些事情:

  1. 手机没电:可以去邻居家/物业充个电,先解决自己会失联的问题。
  2. 家里没电:在物业咨询,在当下,是否有方案可以为家里交上电费。

拆解方法论

从例子中拆解方法论的话,我们应该处理问题的策略是:

  1. 找到我们的问题都有哪些?很多时候,导致我们陷入困境的问题不是一个,而是多个问题交织在一起(一个问题往往直接解决就好了)
  2. 为问题排出重要、紧急的优先级:我们需要为问题设定优先级,根据一个事情发生的最坏后果、是否有可替代方案等方式排序,找到最重要最紧急的问题。
  3. 按照优先级解决问题:当我们排出问题的优先级,下一步要做的就是解决问题。

总结

在生活中,我们常常会 get into troubles,这个时候,静下心来,梳理问题,寻求解决方案,而不是停留在原地,任由恐慌的情绪如潮水般涌上心头才是一个更好的方案。

灵光一闪

做共赢的事情

这篇文章算是为什么选择品牌广告而不是联盟广告的一个延伸。

和一般博客主来说,我的选择显得与众不同,我没有选择一个广告联盟来达成自己的收益的目标。

主要有以下几个原因:

1. 品牌广告更可控,调性更稳定

作为一个技术 & 生活博主,我的读者要么是纯粹来看我的生活的,要么是看我的技术文章的,要么是先看技术文章再来看我的生活碎碎念的。虽然大家来看的理由不一定相同,但至少大家是有基本的辨别能力和素养的。

对于这样的读者而言,你推送诸如 XX蓝月的广告,可能意义不大,甚至会影响阅读体验。因此,从这个角度而言,我并不希望我的读者来到我的博客会看到一些不符合我博客调性内容的广告。

2. 品牌广告可筛选,有效筛选出无效产品

对我来说,虽然有钱赚挺好的,但不代表着我一定会接受某家的广告。品牌广告是一个双选的过程,我可以和我喜欢的品牌商去探讨赞助的费用和收益。当我们达成一致以后再进行投放。

这样,我就可以为我的读者筛选出我自己真正在使用的产品。对于我的读者更好。

3. 品牌广告相比于联盟广告,可以更容易达成共赢

品牌广告的内容是经过我洽谈、使用过的产品,因此在产品质量上有保障。这对于读者来说,他们接收到的信息不是粗制滥造的产品,对他们来说不算一件坏事;对于我来说,我的文章阅读体验没有太多的下降,因此也算一个可以接受的结果。而对于品牌方来说,他的广告投放是有明确的筛选的,定向投放,也会更好。

从上面的这些角度来看,品牌广告的优势还是大于联盟广告的。不过,品牌广告也有自己的问题

  1. 你需要自己维护客户:品牌广告和联盟广告不同,没有人帮你洽谈广告,很有可能今年他投了广告,明年他就不投了。这时你就需要自己去洽谈新的客户。
  2. 收入不稳定,存在空窗期:品牌广告存在洽谈和商讨的过程,就很容易出现广告的空窗期。空窗期意味这段时间没有收入。对于一些站点来说,是不可接受的。
  3. 对小站点不友好:我的博客写了 8 年,有据可查的就有 6 年,对于很多刚刚开始的小站点而言,他们是很难接受到品牌广告的。所以这些也是一些限制。

总结

品牌广告是一个共赢的事情,而联盟广告在未经筛选的情况下,是一个很难做到共赢的事情。对于博客主来说,很难说某一个选择就是最好的。放在 6 年后,我选择品牌广告,但放在写博客的第二年,我可能就会选择联盟广告。

根据自己的需求选择你的广告方案,并坚持的执行下去。

1 US dollar banknote close-up photography

找我帮你做事,如何收费?

本文主要是用于有上门的客户找到我时,方便说明我的计费模式和思路。

TL;DR

我的计费模式为按时间计费,我会使用 Clockify 为你的项目进行时间记录,并由 Clockify 来完成费用的计算。我目前的每小时的单价是 $300/h(按时价折合人民币)

完成一个项目或项目累计时间超过 10 个小时后,我会想你发送计费清单(计费清单参考下方文件),你需要按照计费清单支付我的费用(如果计费清单中的某一项你任务有问题,我们可以重新讨论 & 评估)

为什么不做计件计费?

计件计费的好处是项目从开始的时候,预算就是明确的,你的支出是明确的。但在我看来,计件计费的问题是将你我放在了一个对立面。

可以简单思考,如果某个项目按计时制是 10 小时,那么按计件计费的情况下会出现三种情况:

  1. 我预估时报了超出 10 小时的计件报价:这个时候你会觉得我是不是在咋唬你,这个事情为什么会这么贵。而对于我来说,时间超出,剩下的都是赚的。你不满意,我满意。
  2. 我预估时报了刚好 10 小时的计价报价:这个时候是最完美的情况,你不会觉得我白嫖,对我来说,没有多花时间, 也可以接受。你满意,我满意。
  3. 我预估时报了不足 10 小时的计价报价:这个时候对于你来说是划算的,但对于我来说,我会觉得自己亏了。这个时候可能会在一些可有可无的细节上选择干脆不搞。或随便搞搞就行。你觉得你赚了?但你真的赚了么?你满意,我不满意。

可以看到,按计价计费的时候,有三分之一的概率让你我双方都满意。三分之二的概率让你我中有一方不满意。

此外,这里还有两个隐含的前提 :

  1. 项目的需求不做改动。但不做改动并不是一件好事,如果我们在项目开发过程中发现前期的需求设计有问题,需要加功能,做就要另外加钱,不做,产品无法满足要求。
  2. 项目的时间预估十分准确:项目的时间预估是需要配合着一个非常完善的 PRD 来进行的。但你应该不是那种十分完善的 PRD (完善是指考虑到所有可能的情况,一个 PRD 可能十几二十页 PDF 的那种)。在 PRD 不完善的情况下,预估时间是无法做到准确的。只能按照超出项目时间来评估(延展阅读:侯世达定律)。

计时计费对你我的好处

前面说了计件计费的劣势,那我们来聊聊计时计费对你我的好处:

  1. 计费透明:我在做每一项工作的时候,都会记录在 Clockify 当中,让你明确每一个步骤我在哪一天花费了多少时间。你可以根据我所花费的时间来支付费用,而不是支付一个固定的价格。对于你、我来说,都不是一件坏事。
  2. 为项目好的方向进发:因为我们不再是对立面,那么我们可以向着项目最优解的方向进发。如果某个细节可以让你的产品得到更好的体验,我就会选择帮你加上这个细节。让你的项目体验做到最好。

当然,计时计费也有坏处:

  1. 预算不明确:计时计费只是给出一个大致的预算,实际计费是按照所消耗的时间来计费的,因此,对于强预算需求的项目来说,这可能是个问题。

总结

如果你希望计件计费,那可以不用受累联系我,对于计件计费的项目,我一概是拒绝的。而如果是计时计费,且可以接受我的报价,那么欢迎你通过微信、邮箱等方式联系我。

b29692084bbb

什么是我眼中好的开发者产品的文档?(一)

我自己作为开发者使用过很多的开发产品,也看过不少的文档。最近频繁受邀针对不同的产品的文档提出建议,单独写这样一篇文章来说明一下我觉得什么是好的文档。一方面,可以帮助更多的开发者产品变得更好,另一方面,也可以用于自省,我自己在设计产品时是否会有类似的问题。

不过也需要注意,这篇文档仅涉及 「Guide」和「API Documentation」的部分,对于更多的 Changelog、Example、Tools 、 SDK 则没有涉及,这部分留待后续再写。

本文当中参考了包括:Notion 开发者文档微信小程序开发者文档声网 Agora 开发者文档WordPress 开发者文档飞书开发者文档等开发者产品。

API Documentation vs Guide

其实不少的产品文档写的都是 API Reference ,而不是 Guide,二者在实际的使用意义上是有所不同的。

  • Guide 帮助开发者快速上手一件事,从 0 开始,完成一件事。这是「用户视角」
  • API Reference 则是告诉开发者你能使用我的产品做什么事情。这是「平台视角」

一个好的文档应该是二者兼备的,这样才能一方面降低开发者的进入门槛(Guide 负责),另一方面, 可以让开发者可以知晓能力的范畴,帮助开发者尽可能拓展的应用边界,创造出美好的体验和新的世界。

一个好的 Guide 应该是什么样的?

这里我们以 Notion 的文档为例:

1. 一个好的 Guide 应该尽可能的显眼 & 好找

作为一个新的开发者,进入一个新的开发者平台时时迷茫的:“我应该做什么?”、“我应该看什么?“

这时一个明确的「Guide」、「Get started」可以帮助我们快速找到一个开始的锚点,这个锚点会成为开发者在这个平台中开始进行的下一步。

d2b5ca33bd970f64a6301fa75ae2eb22 11
Notion 开发者文档首页中 Guides 的入口
d2b5ca33bd970f64a6301fa75ae2eb22 12
微信小程序开发者文档中的指南的入口

2. 一个好的 Guide 应该有明确的步骤描述 & TOC

开发者在进入一个新的平台时,需要的是「快速跑完流程,以熟悉平台的各项基本功能」,而不是需要了解到所有的能力(如果开发者已经非常熟悉你的产品,其实根本不会看 Guide,直接去对应的 API Documentation 查看实现了)。

一个明确的步骤描述和 TOC 可以帮助开发者降低心理压力,并让用户找到自己所在的位置,进行下一步的推进。步骤的名称也非常的重要,一个清晰明确的步骤,可以帮助开发者快速明确自己要做什么事情,不会产生疑惑。

d2b5ca33bd970f64a6301fa75ae2eb22 13
Notion 文档当中对于步骤描述
d2b5ca33bd970f64a6301fa75ae2eb22 16
声网文档中关于步骤的描述

此外,也需要注意,步骤不建议太多,可以移除掉那些非核心的步骤,重要的是帮助用户跑通开发流程

3. 一个好的 Guide 应该是场景相关的

开发者在使用产品进行产品开发时,会有明确的预期,我要做什么事情。但产品需求和平台的能力是不同的。我们很难将产品需求和平台能力直接挂钩,这时就需要开发者盲人摸象般在整个平台上搜索和查看,找到适合自己的文档。这个时候,如果有一个场景相关的 Guide,可以帮助开发者快速找到适合自己的场景,并进行文档的细分。

在这些文档中,你的目的是帮助开发者快速了解在你平台上某个方向的能力、核心概念和如何组合你所提供的能力,帮助开发者快速实现自己的业务诉求。

d2b5ca33bd970f64a6301fa75ae2eb22 15
Notion 文档中的场景化文档
d2b5ca33bd970f64a6301fa75ae2eb22 18
微信开发者平台的场景化介绍

一个好的 API Documentation 应该是什么样的?

如果说 Guide 是开发者进入一个平台的时候最基础的教程文档。API Documentation 则是一个开发平台中最为核心的部分了,开发者每天都需要与 API Documentation 打交道,以完成一项工作,如果 API Documentation 做的不好,那对于开发者来说,简直就是一个灾难。

1. 一个好的 API Documentation 应该是组织合理的

API Documentation 当中往往包含了大量的信息,那么合理的拆分不同的 API 的模块,可以帮助开发者无需遍历所有的 API ,而是直接按照模块逐级查找自己所需的 API 即可,可以有效的提升查找的效率。

d2b5ca33bd970f64a6301fa75ae2eb22 19
Notion 文档当中按照业务模块拆分的 API Documentation

2. 一个好的 API Documentation 应该具备所涉及到的各项数据结构的说明

对于复杂的 API 接口来说,参数/返回值往往不仅仅是一个简单的 Integer 、String ,还会涉及到一些更加复杂的结构化数据的定义。

一种选择是将这种复杂的结构化数据抽象出来,成为一个新的类型;另一种选择是每次都解释一遍。显然,根据软件工程的 “DRY” 原则,我们应当将其抽象出来。在将对应的数据结构抽象出来后,需要注意的是,将其放在一个明确的位置进行展示和说明。原则上,这些结构的说明应该先于具体的接口说明。

d2b5ca33bd970f64a6301fa75ae2eb22 20
Notion 文档中的 Database Object 的位置说明
d2b5ca33bd970f64a6301fa75ae2eb22 21
WordPress 文档中关于返回类的定义描述
d2b5ca33bd970f64a6301fa75ae2eb22 22
WordPress 中在返回值中说明的错误类的入口

3. 一个好的 API Documentation 应该提供相应的 Sample Code

对于开发者来说,Talk is cheap, show me code。而在开发领域也是同样的。你提供的 Sample Code (甚至是在线的调用测试),都可以帮助开发者更好的理解相关的能力和开发逻辑。

所有的细节,都在 Sample Code 中一览无余。

d2b5ca33bd970f64a6301fa75ae2eb22 23
Notion API Documentation 中生成代码的部分

4. 一个好的 API Documentation 应该可以提供上下游关系

在 WordPress 文档中,有一个我非常喜欢的功能就是 Related 。Related 内部分为 Uses Used By,分别介绍了某个函数都是用了哪些函数来完成自己的功能和哪些函数使用本函数完成自己的功能。

d2b5ca33bd970f64a6301fa75ae2eb22 24
WordPress 文档中 Related 的部分说明
d2b5ca33bd970f64a6301fa75ae2eb22 28
声网文档中关于 API 上下游的描述

伴随着 Uses 还提供了这个函数的源码(不过这个对于平台类型的产品不能直接照抄),这样我可以非常清晰的参考这个函数的 Uses 和源码,以了解这个函数是如何实现自己的功能的。这样当我需要的时候,就可以非常方便的基于这个函数,改造出一个我自己使用的函数。

而 Used By ,则提供了其他的函数是如何使用这个函数的。对于一些我比较陌生的函数,可以直接参考其他函数的用法。从某种意义上来看,这是比测试用例更加全面的用法的说明,因为这是在“生产环境”下的用法。

我们在开源世界如果没有文档,会看测试用例,那么在 WordPress 当中,我会看的是 Used By。

5. 一个好的 API Documentation 可以提供用户之间的沟通渠道

我在 WordPress 开发者文档当中,还会常用到的一个功能是 —— User Contributed Notes。这个功能为开发者提供了一个基于函数的共建笔记。开发者可以自发的在其中撰写自己针对这个函数的开发经验。

d2b5ca33bd970f64a6301fa75ae2eb22 25
WordPress 文档中 User Contributed Notes

当我在不知道某个函数应该怎么使用的时候,我往往会去 User Contributed Notes 去找找看,看看别人是如何使用某一个函数的。官方的文档往往无法跳出「我有什么」的思路,而用户的共建笔记则可以共享出开发者使用某个函数的「奇技淫巧」。这些「奇技淫巧」让开发者的产品显得与众不同,也可以进一步的扩大产品的范畴。

总结

一个好的开发者产品文档是什么样的我很难定义,但至少上述的这些点,确实让我使用这些平台的产品在开发应用和业务的时候变得更加坚定。希望我的这些笔记,可以帮助到你,让你也可以涉及出一个好的开发者文档。

a man holds his head while sitting on a sofa

如何缓解焦虑

我常年处在焦虑的状态中,焦虑行将踏错,焦虑无法达成自己的预期,焦虑无法达成他人的预期。这些焦虑久而久之,会让我拖延症发错,将所有的事情都拖到一个无法挽回的境地。然后再破罐子破摔,重头再来。

次数多了,也开始寻求一些方式和方法来缓解自己的压力。

我最近的缓解压力的方式是重新装修自己的办公环境,让自己可以更加舒服的办公,一个全新的、干净的办公环境会让我感到轻松。

整理后的办公环境
如何缓解焦虑
7423a3c685ae859e7d5283b7e1b33c4c

关于 ASoul 事件的一些思考

我自己其实不太了解 ASoul,也没有特别的关注,毕竟作为一个社牛,不太会通过虚拟人来获取情绪价值。但我确实之前听说过 VTuber,在我的下意识以为,VTuber 的声音应该是由 AI 来完成生成,工程师建模,PM/运营来负责脚本的产出(类似微软小冰)。

不过,现实可能是 ASoul 这样的项目其实是由中之人来完成声音的录制,更接近于传统的声优的角色。对于资本来说,中之人就是一个耗材,但对于喜爱 VTuber 的人来说,中之人是非常重要的。

当一个 VTuber 之后是一个独立的人的时候,其实能贡献的当然不只是声音的问题,还可以贡献出更多的情绪价值。而这些情绪价值,正是一个 VTuber 的独特的价值。

这些东西是完全无法通过 AI 生成的么?可能是可以生成的,但暂时可能无法生成。随着技术的进步,逐步拆解出人的各种情绪和诉求,再由 AI 来完成生成,实现真正意义上的 VTuber

A group of friends at a coffee shop

情分和本分

我们在生活中,需要注意情分和本分的区别。不要错把本分当情分,把情分当本分。

举个例子来说,

假设我当前的房子快要到期,我找了一个新的空房间。为了减少租期的重叠,我与房东达成了一致,在两周后入住。

但因为我自己的原因,不得已需要提前入住,这个时候我和房东沟通,说我是否可以提前入住?房东同意我提前入住。

在这个事情当中,房东同意我入住是情分,房东不同意我入住是本分,因为我们的合同签署的入住日期是两周后,即使不允许我入住,我必须出去住酒店,也是因为合同签署的确实是两周后,这也是合法合理的。

在生活中我们需要感谢别人的情分,感谢他人的帮助。但同时也要明白,别人遵循本分做事并没有什么不对,人家只是遵照合同办事,没有过错。

brown short coated dog on brown wooden table

被种草 & 断舍离

我算是一个被「消费主义」洗脑的人,很喜欢买各种各样的东西,比如:

  • 我家中有三台电脑:一台 mac mini 2012 (主力使用);一台 mac book pro 16寸(出差使用);一台 NUC(用来做一些 Windows Only 的事情)
  • 我家中有多个水壶:一个京造的手冲壶(用来冲挂耳);一个小熊的蒸茶壶(用来蒸煮我的各种茶叶);一个大的烧水壶;

我买了很多东西,其中一部分是我自己生活需求的延展所带来的,另外的一部分,则是来自于被各种视频/朋友推荐。

我买的制冰机便是一个典型的例子:

我是在津津乐道的节目当中听到大家推荐居家好物的时候,提到了制冰机,以及制冰机带来的畅快感,就买了制冰机。

而我购买产品的逻辑倒是也十分简单:我不太会听陌生人的推荐,而更相信一些有着持续关系和持续口碑的人的推荐。在我看来,靠谱的人推荐的产品大多是靠谱的,不靠谱的人推荐的产品是不可信的。

最近,又快要到搬家了。准备继续寻找一个更加低成本生活的方式。届时,又是一次断舍离。

当我的东西变少的时候,确实,生活变得更快乐一些(就像我们想要去露营,体验的一方面是大自然的美妙,另一方面,则是对于逼仄生活的反抗。)