分类目录归档:随笔

close up photography of gray engine part

IT企业的价值在何处?

一直以来,大家都以进入互联网企业为荣,绝大多数人都在想这个问题。

但,价值是否真的在互联网?

一直以来,互联网企业都因为工资高等特点被广大开发者所关注,但随着互联网的增量减少,很显然,互联网的高工资难以维持。互联网对于工程师的诉求也会逐渐的减少。

在这个时候,每一个软件工程师都需要思考的一个问题是 —— 如何在这样的大背景下生存?

一个是找到有增量的互联网市场 —— 比如出海,到第三世界国家去进行产品开发(不一定人要去,但至少业务要去)。在这个市场,竞争不那么激烈,你依然可以维持高增长,获得更高的收益。

另一个是可以思考 IT 企业的本真价值是什么?互联网企业也好、软件企业也好,本质上是通过提升效率,让过去不好做的事情现在变得更加简单(微信提升了沟通的效率、淘宝提高了交易的效率、微博/Twitter 提升了发布观点的效率)。因此而产生价值。

而被互联网化/数字化的行业和领域并没有我们想象的那么多,大量的行业都还在使用一些非常传统和古朴的手段来进行信息的处理和交互,这些行业值得软件企业/互联网企业深耕,推进更多的企业数字化,并跟随这些企业的数字化来产生价值。

不过,也需要注意的是,无论是方案一,还是方案二,都已经不是「捡钱」的难度了,都需要你深耕行业,并在深耕的基础之上,创造价值,才能收获相应的反馈。

photo of bulb artwork

为什么我会订阅那么多播客/Blog/微信公众号

作为一个创作者,我对于自己的要求不算高,但也不算低 —— 我希望我能持续有输出。

但我也深知,我是一个普通人,我无法让自己永远有的写,永远有的说。为了解决这个问题,我给自己提供的解决办法是 —— 让自己沉浸在足够的信息当中。

我的逻辑是 —— 我写的文章大多并不是完全创新的(技术的除外),这些文章的灵感来自于我每天的所思所想,而所思所想来自于我的摄入。如果希望有足够的输出,足够的摄入是不可或缺的。

基于上述的逻辑,我得出了我应该做的事情 —— 尽可能多的订阅播客/Blog/微信公众号,收集到尽可能多的信息,然后从这些信息中筛选出我自己所需要的,并与其产生互动(比如诞生一个新的灵感)。

从某种意义上来说,我能够有这么多的文章灵感、软件的灵感,都来自于我的这些海量的输入。

当然,这些海量的输入也为我带来一些不爽的点 —— 比如,信息量太大了,我往往是无法看完所有的信息(当然,我也不太强求自己能看完所有的信息),也在追寻更好的信息摄入的方法,希望自己可以更加轻松的处理这些信息。

woman spreading hair at during sunset

做让你快乐的事情

昨天和一个朋友聊,这个朋友在现有的公司做的不开心,觉得现有的公司已经脱离了他早期加入公司时的样子,想要离开现在的公司,寻求 Web3 公司的机会。

对我来说,我给到的建议自然是肯定的。

这个朋友在开源社区呆了很久,也有了自己的影响力和人脉,在我看来,他已经脱离了求生存的阶段,已经不会因为离开当前的公司就完全无法生存,他完全可以找到一份适合自己的工作。既然如此,为什么不选择一个能够让自己开心的同时,还能赚到钱的工作?

对于 90 后这一代人而言,我们当中的有些人还在奋斗的途中,但也确实有他这样的,其实家境还可以(不需要他奋斗脱贫),上一代人打下来良好的基础,让我们可以选择去做自己喜欢的事情,就没必要完全浪费自己的生命和时间在一些自己不喜欢的事情上。

勇敢的走出现在,去做你想做的事情吧。

blue Work Harder neon signage

奋斗

前两天看到 V2ex 的一个帖子,提到了关于奋斗,正好也聊聊我自己关于奋斗的看法。

我其实一直都明白,我不是很聪明,我只有中人之姿(普通人的资质),因此,我不奢望能够与同龄人当中的优秀者比,因为我知道,我真的比不过,别人用一小时可以做完我需要用五个小时才能做完的事情。

但,天资不够不意味着不需要努力,对于我们每一个人来说,我们的奋斗,是为了让自己从当前的起点,进入到一个新的高度,而不是和天才做比较。哪怕我们奋斗到的新的高度,也不过是别的人起点,但至少相比于曾经的自己,我们达到了一个更高的高度,获得了更好的生活。

如图所示
灵光一闪

灵感: 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 开头的列车可以以一个比较低成本把你送到千里之外。

深圳东至武昌 Z/T列车

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

深圳北至武汉 G 列车

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

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

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

西湖边,特价只需 49 一晚

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

总结

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

构建自己的应急处理机制

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

看个例子

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

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

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

总结

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

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

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

不过也需要注意,这篇文档仅涉及 「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」可以帮助我们快速找到一个开始的锚点,这个锚点会成为开发者在这个平台中开始进行的下一步。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Notion API Documentation 中生成代码的部分

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

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

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

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

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

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

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

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

WordPress 文档中 User Contributed Notes

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

总结

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