“Moving away from UUIDs”, Really?

Recently I saw an article called Moving away from UUIDs – Neil Madden on Hacker News. The title immediately got my attention since I use UUIDs a lot in various projects, no matter personal or commercial. Whether I’m using it right or wrong is a vital concern from an engineering perspective, so I read it thoroughly and carefully. This article is my summary and thoughts on it.

Overall, the author gives an opinion that using UUIDs for unguessable random string like session tokens or cookies is a bad practice, the reasons are as follows:

  1. UUID is insecure in cryptography. In some situations, an attacker can take only 35 minutes to brute-force guess a valid result.
  2. UUID is inefficient in storing data. Because of its hexadecimal format and the use of extra dashes, a UUID takes 36 characters to represent 16 bytes of data.

As a replacement, the author suggests to use a 20 bytes random string that is URL-safe base64-encoded. Here’s an example comparing with an UUID string:

20 bytes base64 random: Xl3S2itovd5CDS7cKSNvml4_ODA
UUID                  : 5a097fe7-1720-457c-8363-8d660a65bab2

The advantages over UUIDs are:

  1. A 20 bytes random value is almost impossible to guess in a reasonable time.
  2. The length of the string is just 224 characters, resulting in much less storage space than UUIDs.

Generally speaking, I think although the conclusion of not using UUIDs for tokens is correct, the assumption is totally wrong. UUID (Universally unique identifier) as the name says, is an ID which should not be used for cryptographic purposes in the first place. The proper scenario for UUIDs is using it as primary keys in distributed systems, in which it prevents collisions without relying on a centralized identity generator. In contrast, random string has no way to achieve that.

I did learn something new from this article, but it failed to give me anything useful upon my understanding of how UUIDs should be used.

Do not write clickbait posts, as being neutral and accurate is a virtue for engineers.

离开国产 SaaS

昨天看到 @dingyi 的推文说:

国产软件真的没必要轻易尝试了……

原因是蜘蛛笔记发布了一个公告1,这款诞生不到半年的国产笔记服务因「战略调整」即将停止运营,甚至没有走出测试阶段,非常令人唏嘘,推友对此的猜测大都集中在行业萧条和内容审查上。

虽然不再尝试国产软件说得有些重,但我非常理解这种心情,因为我也认为,现在国内已经不再适合小公司的 SaaS 生存了。 在国内内容审查持续变严的大背景下,个人和小团体开发者将日渐减少,因为它们根本无法负担起内容审查的时间和金钱成本。 不久之前内容销售平台面包多暂时关停,随后创始人 DK 发布了公告2,表示在恢复后平台的敏感度和审查度都会大幅提高,以确保面包多可以在日益严苛的监管条件下存活下去。

站在行业生态的角度,我对国产应用总是抱有着鼓励和期盼,但站在个人用户的立场,我选择从现在开始尽可能不把重要数据放在国内小公司开发的线上服务上。毕竟数据的重要性高于一切。在服务随时可能关停、数据随时可能因审查而消失的情况下,真的没办法安心使用下去。

下面盘点一些我正在使用的包含重要数据的工具服务,并给出关于迁移方式和替代产品的建议:

CategoryServiceMigrationAlternatives
网页保存CuboxCubox 国际版Pinboard Upgrade
Mem.ai
Raindrop.io
wallabag
HamsterBase
待办清单滴答清单国际版: TickTickTodoist
书影音记录Douban豆伴:豆瓣账号备份工具NeoDB
生词本Eudic生词本同时存在于本地和云端,
导出也非常方便3,因此无需担心
目前还没见过其他
有云同步功能的字典软件
笔记石墨/语雀/wolai等我在这些服务上的文档很少,手动下载即可Notion, Obsidian

Defeat VSCode Tab Bar

A while ago, I found my VSCode tab bar (or tool bar) UI was quite unstable. The reason was that extensions may add icons called “action button” on the right side of the tab bar according to the type of the file, so when switching back and forth between different kinds of files, these buttons will either show or hide, making the available spaces for tabs changing constantly. This may not be noticable when you just open a few tabs, but if you have tabs that are enough to take up the spaces of the tab bar, the whole tab bar will be a clown fiesta with the appearace and disappearance of the action buttons. Tabs are flickering due to their width change, the last one could even be pushed to the next line. It’s just so eyes-hurting and annoying.

After realizing who was the culprit, I immediately started to search for a solution. Sadly, VSCode itself did not provide a way to customize the side bar, but I was luck to find an extension called Customize UI, which allows me to inject css into the application, so that hack the UI whatever I want. I installed the two extensions and add the following lines of code in settings.json and boom, the world was quiet again.

{
    "customizeUI.stylesheet": {
        ".editor-actions": "display: none !important;",
    }
}

But this solution is not perfect, because Customize UI relies on the Monkey Patch Extension to achieve UI hacking, which always requires me to restart the VSCode immediately after I open it. That’s fine, I told myself, as long as I can get ride of those tab bar icons.

Today, I updated VSCode and was surprised to find that VSCode finally implemented a feature called Hide actions from tool bars, it says:

You can now hide actions from tool bars. Right-click on any action in a tool bar and select its hide command or any of the toggle commands. Hidden actions are moved to the … More Actions menu and can be invoked from there.

This means I can hide those buttons without th need of using the clumsy extensions. I tried to right click on an action button and select “Hide …”, it disappeared as expected. Then I uninstalled Customize UI and hide all the action buttons one by one. So yeah, this is the story of how I defeat the VSCode tab bar.

真正的好作品只能靠自己去发现

最近闲暇时间在看一本网络小说,名叫《异仙列传》,作者是流浪的蛤蟆。

蛤蟆是一位非常老资历的网文作者,我从 2008 年接触他的小说《蜀山》开始,不定期关注他的更新。蛤蟆的小说总是给人天马行空的感觉,想象力非常独特,情节自然流畅,主角大都洒脱不羁,仙气和痞气并存,有种与众不同的魅力。虽然许多书都没有完本(俗称「太监」),但读起来总是手不释卷,活泼泼让人快乐起来。

但这样一位有才华的作者,却一直没有多少读者认识他,为什么呢?

在网络小说发端的蒙昧时期,创作难,受众小,许多作者虽然创造出了很好的作品,但受限于市场,他们得到关注和回报都非常有限。后来,以唐家三少、我吃西红柿、天蚕土豆、梦入神机为代表的一批年轻作者,依靠简单的文笔、俗套但有爽点的剧情、极高的更新速率,让网络小说真正走进了普罗大众的生活中。网络小说的创作和阅读门槛被大大降低,与通俗文学渐行渐远,逐渐形成了现在无脑、爽文的刻板印象。

网络小说的发展史,就是一个劣币驱逐良币的过程。好的作品不会过于套路化,因为有追求的创作者总是在尝试突破和创新,因此不仅生产效率不会太高,还需要读者有一定的耐心和智力才能渐入佳境。但大众读者所需要的,其实不是文学意义上的好作品,而是一种工业品,即通俗易懂、能在尽可能短的时间里带来刺激和反馈的大量文字,并能持续稳定的获得。这些需求与好作品的创作条件背道而驰,不愿改变的作者自然难以成为主流。

这让我再次感受到,大众认为好的不一定对自己而言是好的。被大众认可,意味着要满足普适性的需求。要通俗易懂——简单无脑;要政治正确——阉割思想;要适合传播——利用人性的弱点,消费用户而不是被用户消费。在文学、影视、音乐、游戏这些由个人品味和主观感受来判断好坏的领域,普适很可能是对自己而言的不适。

所以,不要去看什么豆瓣电影 Top 250、网易云音乐热门推荐、Steam 畅销周榜了, 真正的好作品只能靠自己去发现。保持好奇心和对美的追求,它们会带你走向精神世界的探索之路。

P.S. 我关注的老资历而鲜有人知的网文作者,还有兰帝魅晨。另外,读者如果想了解早期优秀的网络小说,可以去搜索「网络文学十年盘点」。

我用过的位置追踪应用

国庆接连几天都在外面游玩,拍了许多照片,于是产生了一个想法:

有没有哪个 app 可以导入一堆照片然后把其中的地理位置信息连成一个轨迹?

在 Twitter 和 Telegram 上都被推荐了「一生足迹」这个 app,让我回忆起了之前用过的几款类似的应用,于是把它们一起记录如下。

  • Moves

    接触的第一款位置追踪应用,也是最喜欢的一个。除了有些耗电,各方面都几乎完美。我从 2014 年开始重度使用了一两年的时间,最后因为厌倦了手机发热而放弃。

    2018 年 Moves 被 Facebook 关闭,成为 FAANG 资本化的又一个牺牲品 https://about.fb.com/news/2018/07/hello-tbh-moving-on/

    In 2014, we bought the fitness app Moves. It records your daily activity — including walking, cycling and running. We’re deprecating the Moves app and Moves API on July 31.

  • Gyroscope

    2016 知道这款应用,一开始觉得很漂亮,但很快就审美疲劳了。Gyroscope 并非纯粹的位置记录工具,而是包含了各种 quantified-self 数据,却又做的非常社交化。我对分享自己的隐私数据没有什么兴趣,一年的会员结束后就卸载了。

  • Arc

    Moves 关闭没多久,出于对它的怀念,我找到了 Arc。客观的讲,Arc 也是一个足够优秀的应用,功能简单直接,没有什么多余的东西,但设计上平平无奇,没有了最初 Moves 给人的惊艳感受。

  • 一生足迹

    出自国内开发者之手,最大的特点是把省电这件事研究到了极致,果然优秀的创作者自己才是真正的用户。经过简短的试用,我确定这是目前最好的同类产品。

    不过一生足迹虽然可以导入照片中的位置信息,却没法将其连成轨迹,我只能继续寻觅其他 app,或者想办法自己实现了。

为什么人们在黄图群喜欢聊哲学

偶然看到一张网图,内容如下:

人类真矛盾,不管进啥群,最后都是搞黄色。反而进了黄色群,最后聊三观、聊实事。

以前也看过类似的说法,都一笑置之了,这次忽然觉得背后可能有着一定的心理学逻辑。

让我们来看看马斯洛需求层次 (Maslow’s hierarchy of needs) 这个广为人知的心理学理论。(中文世界里一般是五种,英文维基百科里有八种,这种差别让我忍不住想起 OSI 模型的四层与七层)

需求Need说明
生理Physiological级别最低、最急迫的需求,如:食物、水、空气、睡眠、
安全Safety对人身安全、生活稳定以及免遭痛苦、威胁或疾病、身体健康以及有自己的财产等与自身安全感有关的事情。
爱和归属Love and social belonging较高层的需求,常称为“社交需求”,如对友谊、爱情以及隶属关系的需求
尊重Esteem成就、名声、地位和晋升机会等。尊严需求既包括对成就或自我价值的个人感觉,也包括他人对自己的认可与尊重。
自我实现Self-actualization最高层的需求,包括针对于真善美至高人生境界获得的需求

以马斯洛需求层次来分析,许多人长期生活在性的需求得不到满足的状态下,「生理」这项需求占据了思想的主导,导致无心探讨群聊原本的话题,最终有意无意地开始性有关的交流。这就是为什么会产生「一切群最终都会变成黄图群」的情况。当然,这只是一种玩笑和夸张的说法,不能代表全部。

而黄图群则不同,由于摆明车马就是来搞黄色的,成员中一定有精通此道的行家,他们在性这一方面有能力得到满足,需求层次就会上升到社交和认知相关的区域,在群里聊起哲学话题就不让人意外了。

说到这里,我忽然想起朋友对技术群的吐槽。有些技术群虽然不搞黄色,却会有很多争论——哪个语言更好,哪个框架不好,为什么用A而不是用B——并且总是会上升到划分阵营、形成鄙视链的程度。用马斯洛的理论来看,或许是为了「尊重」这一需求吧:站定一个立场,维护自身的正确性,来获得他人的认可。不过我觉得要警惕这一行为,因为通过「做」而不是「说」来获得尊重和认同更有价值一些不是吗?

并不乐观的全球化

看到了 @waylybaye 的推文:

我一个人,一台电脑,一个银行账户,不需要任何资质证明,不需要任何政府部门审批,不需要和市场所在地的政府打交道。就可以把作品卖到全世界,收全世界的货币,在全世界交税。全球化真的是一个奇迹。

总觉得哪里怪怪的。它的逻辑是:因为我仅使用任何人可以拥有的设备和条件,就能够将作品卖到全世界,所以我赞美全球化。可事实真的是这样吗?

首先,把产品卖到全世界的是 Apple Inc. 而不是开发者个人。开发者付出 15% 的收入分成为代价,使用苹果所建立的全球化合规和销售渠道。开发者不是自由的,甚至无法以苹果以外的方式为收款渠道。从生意的角度讲,这并不是什么坏事,各取所需互惠互利罢了。但是,一个人把 App 放在 Apple 商店向全世界销售这件事,不应该用于评价「全球化」是如何的。

所以这是全球化的奇迹吗?这只是苹果强大的市场能力的体现。实现全球化的是 Apple 而不是我们个人,Apple 与开发者之间只是一种商业关系。如果有一天,Apple 对来自中国的开发者采用更严格的限制政策,一切都可能成空。

真正的全球化,是个人触及世界各地的渠道和能力。在 Apple 这个渠道之外,个人开发者想要将自己的产品卖向全世界,仍是步履维艰。

实际上全球化正在变得越来越差,我自己在和美国的商业、移民政策打交道时深有感触。即便没有这些经历,国与国之间变得越来越封闭也是任何有基本常识的人,所能感受到的显而易见的事实。


如今社交媒体上充斥着为个人利益而扭曲思想的言论。只说了「不需要什么」,却没说「需要什么」;只展示「就可以」,却忽略「不可以」。「假话全不说,真话不全说」,这样的表达方式是对信息的误导,但有利于传播。因为公众喜欢好听的言论,现在动荡的环境下,赞美全球化能给人带来「世界仍然是美好」的慰藉。

可这正是我所厌恶的,宁愿了解真相而痛苦,不愿欺骗自己而宽心。

童年的 Disco

朋友给我发了一个 B 站视频 别问我什么是迪斯科,是音乐家张蔷 2013 年的歌曲,却有着浓浓的怀旧风情,唤起了五光十色的童年回忆。

于是我翻了翻自己的收藏,给他回发了另一个视频: 当年传唱度过亿的“Dj大舞曲”,DNA储存卡真的被读取了!

溜冰场、点播台、路边特价小卖场,都是这些 Disco 音乐在童年出没的地点。记得上小学时,同学们给我开生日会,女生们还排练了一个舞蹈,曲子是 Smile - Butterfly

这是音乐的一种魅力,与音乐的类型无关,不论是古典的还是现代的、粗糙的或精致的、柔和的或激烈的,只要它触动了你,此刻的感受就会被保存在这段旋律中,许多年后也不会改变。

在都市的夜晚,如果一人独处,不妨逛逛 水晶DJ网,或许会找到一首让你忘却烦恼的 《凤舞九天》

Kevin Kelly 对创作者的指导

最近读到 Kevin Kelly (KK) 的一段话,深有感触:

Separate the processes of creation from improving. You can’t write and edit, or sculpt and polish, or make and analyze at the same time. If you do, the editor stops the creator. While you invent, don’t select. While you sketch, don’t inspect. While you write the first draft, don’t reflect. At the start, the creator mind must be unleashed from judgement.

68 Bits of Unsolicited Advice

放在作为软件工程师的自己身上,creation 就是 building applications,improving 就是 refactoring and algorithms。我们常常讲不要过度优化,那是在宏观的设计层面。而在具体的实现过程中,也不该太在意代码的优化,否则会妨碍自己的创作者思维,拖累从 0 到 1 这个最重要的里程碑的进度。

这并不是说要刻意写出丑陋和低效的代码,而是顺应自身当前的代码素养,不额外付出抛光打磨的精力。维持创造者思维的惯性,专注在将脑中的想法转变为可工作的最小实现的过程中。完成实现后,我们再切换到评审者思维,去重构和优化代码,提升工程能力。这样两件事情都可以做得足够专注、高效。


KK 的个人网站有个名为 LIFESTREAM 的页面,上面是他日常想法的记录和分享。发现这个页面后,我很受震撼。在我的刻板印象中,像 KK 这样的当代著名作家,书籍是一般人了解他思想的唯一途径,他应该生活在自己封闭的圈子里,所见所闻都与我们有着巨大的差异。

如今我发现,他也有自己的互联栖息地,并且持续地保持着与开放世界的信息交换。LIFESTREAM 有时一天两更,有时三四天一更,这位 70 岁的老人有着超过年轻人的旺盛好奇心和创造力。

我非常钦佩 KK,不仅是因为他的思想,更因为他在身体力行的告诉我,什么是一个纯粹的创作者,和一个取悦自己的灵魂。

不换房了,继续向前

前阵子在 如何寻找一个理想的租房 中,讲了最近寻找租房的经历。这篇文章来同步一下后续的进展:我们选择了保持现状,继续居住现在的房子。

为什么呢?我们的目标是降本增效——降低在住房上的开支,提高生活质量和工作效率。我意识到在这两点之间,增效不能为降本妥协。也就是说,如果一个地方租金便宜,但会影响我们的工作效率,是绝对不能接受的。我们在可选的房源中,没有找到符合这一要求的房子,于是便有了这个决定。

事情结束后,我们各自都有一些收获,下面是女友的笔记摘录。

人都是从「他知推动自行」一步步到「自行自知」再到「自知自行」,多次螺旋循环后最终实现「知行合一」。如果前一个过程没有成功完结,就很难推动下一个过程开始。

当你思想中存在诸多矛盾和纠结,不如尝试去行动,让行动检验思想认知。

这里说的是她一开始有了换房的想法,但并不确定,及时行动起来之后,得到新的信息,随后调整目标,知和行得以相互验证和上升。

考察调研的「行」:因为不想为交通便利买单,削减总租房成本,在贝壳上筛选和小红书上做功课后联系中介,花了两天时间考察目标价位的房源。

调研后得出的「知」:杭城的房产市场化程度高。交通、小区环境、周边配套生活设施、房型、室内观景与采光通透度、室内精装修程度这 6 项要素共同决定租房市场的定价。尽管可以在交通方面做一下妥协,但对其他 5 项要素要求高的话也很难找到一套合适的小房子。满足 4 项要素价格相对低的房源在市场上就很抢手,一房难求。目前的房东并不是漫天要价,在 6 项要素都具备的前提下价格高是理所当然的。

认知升级:在无法以相对较低预算交易一套性价比高的房子的情况下,搬家本身消耗精力且需要较长适应期容易打乱目前生活节奏的不可估成本。采取另一种思路——在不削减租房成本的前提下,努力提高单日工作学习效率,增加未来的收益来以降低租房成本的影响。

在几天的「行」之下,最终决定维持现状没有搬家,看似并没有改变,但实际取得建设性成果:对整个租房市场有了进一步的认识,对当下居住环境的重新审视和珍惜,提高租房信息获取能力,认识值得合作的中介朋友,获取一手房源流动性信息和对未来租房对象进行及时调整的能力。

其实生活本身就是我们所要追求的一切,而金钱是生活的燃料,带着喜悦的心情把它投入到这隆隆运转的引擎之中吧。