最近
春节之前,查了一下日历应该是腊月十七,我爷爷去世了。
隔了一两周之后得知,在他去世之前一天或者两天,姑妈想用她的手机给我打视频,让爷爷跟我说说话,但是没打通。我有个「古代」的「国内」微信,但在另一个手机上,那个手机已经很久没开过了。
不知道这两件事有没有关联。
春节之前,查了一下日历应该是腊月十七,我爷爷去世了。
隔了一两周之后得知,在他去世之前一天或者两天,姑妈想用她的手机给我打视频,让爷爷跟我说说话,但是没打通。我有个「古代」的「国内」微信,但在另一个手机上,那个手机已经很久没开过了。
不知道这两件事有没有关联。
2024 年最大的事情可能是中间失业了一个多月。
在上一年(也就是 2023 年)年底的时候,就感觉公司有奇奇怪怪的问题,CEO 自己因为签证的关系回不了瑞典,公司好像没钱了,但似乎是在找投资人谈。当时就在想要不要开始找新工作,但是一方面有拖延症,另一方面又觉得这样的节点撂挑子不太好。
接着到 2024 年初,我开始一边练习 Elixir,一边盘算投简历(实际并没有投多少)。这段时间 CEO 还表现得像往常一样,时不时地跟我们开会,时不时地甩来一些思路混乱的设计让我们实现。终于到 3 月底,公司宣布没钱了,要让我和另外一个码农离职。
中间涉及了一些法律问题,工会介入。于是公司在 4 月初的时候取消了 3 月底的解雇,重新走程序解雇了一遍……实际的效果是 5 月、6 月照常工作,7 月是所谓的「花园假期」(garden leave) 不必工作但是工资照付。其实这几个月也没多少事情,而且也知道即使想推动大的改动,时间也不够了(另一个码农当时在家看孩子,工作时间减半;何况公司的气氛也不对),所以捣鼓了一些 OpenAI 的 API,用 streamlit 写了一个聊天机器人;了解了一下 DDD;还看了一些讲「成功的产品团队如何运作」的书,比如 Inspired。
之后 7 月份闲着也是闲着,给公司用 AnythingLLM 搭了一个 LLM + RAG 的小聊天机器人。部署之后一直不稳定,可能是它里面的 parser 不够稳健吧。
7 月底之后,按道理工会给发 80% 的薪水。但第一步是要在劳动局网站登记失业,我当时精神有点崩溃,晚了两天才去登记。所以那两天的钱拿不到。我登记之后隔了几天,劳动局的大姐打电话问我有什么工作经验、会做什么。讲完之后,大姐如释重负地说:「太好了,你这情况,不需要我局提供培训、指导。」
领钱之前又遇到了小小的阻碍。工会说查了我的纳税记录,中间缺了几个月,所以不能确信我申报的工时是准确的。找老板聊了一下,她又找了会计,隔了一两个星期改正了错误,又通知了工会,这才在 8 月下旬拿到钱。
而且实际的钱是按周发放的,每周需要在工会的失业金网站填「本周无业的天数」,每月在劳动局网站填至少 6 个申请的岗位。
那段时间一直很忐忑,改了简历的文本(还让 ChatGPT 润色了一番),好好捯饬了一下 LinkedIn。同时还不停地写码,作为手艺人,手不能停。这段时间总共投了 38 个岗位,只拿到了两个面试。但 9 月初入职的这家公司并不是投简历拿到的,而是 2022 年聊过一次的公司。公司做的事情刚好也是 LLM + RAG 的系统,玩 Streamlit 和 AnythingLLM 的经历意外地起到了帮助。
2024 年年初的时候是给自己定了一些目标的。比如开始打羽毛球、攀岩,隔天跑步。只有跑步大体坚持了下来,但是也并没有频繁到隔天跑一次。要学开车,但并没有。要瑞典语流利,但并没有投入多少时间和精力。要打开社交圈子,但下半年变得无比自闭。要进一家更好的公司,这一点倒是做到了。
2024 年年初还列了几个想做的小产品,年中还拍着胸脯说要帮朋友写一个她能用到的小工具。但一件都没做成。
第一个错误是 mission creep。打比方说,想做一个凤凰,但是发现做凤凰好难,于是想不如先做一个大雁练手。如此一来,实际动手做的只是一个鹌鹑,但连鹌鹑都没做完。继续沿用这个比喻的话,更好的做法可能是先做凤凰的爪子,而不是放弃凤凰,去做大雁。
另一个错误是企图在做东西的同时学新技术,企图一石二鸟。能一石二鸟固然好,但如果同时有两个目标,人一犯懒就会优先做简单的那个。相对于「做新东西」,学习,也就是临摹已有的东西,显然更容易。虽然宣称是在用 Elixir/Phoenix 写东西,但实际上是花了很多时间学 Elixir 和 Phoenix。(写 Elixir 的手感毫无疑问是美妙的。但是怎么用 Elixir/Phoenix 写出自己实际想要的效果,却需要重新拧一遍脑袋里的螺丝,相当伤脑筋的。)优先做困难的事情比较好。
始料未及的事情是今年又读了一大堆励志文献。比如 Cate Hall 的文章「如何更有主观能动性」(How to be More Agentic),比如 Shreyas Doshi 的「要提高主观能动性」(High Agency),再比如「高效能人士的七个习惯」。更始料未及的是,意识到里面的道理都还挺对的。
另外一本很重要的书是许成钢的「制度基因:中国制度与极权主义制度的起源」。我还没看完,但是这本书的框架实在太厉害了,推荐大家都看看。
这个 blog 一直是用自己写的静态网站生成器 (Static-Site Generator),从一堆 Markdown 文件里生成 HTML,再用 git 推到 Cloudflare Pages 上。
之前的生成器是 Python 写的。本来一直能用,然而去年有一天,一个 dependency 不知怎么回事坏掉了。(有可能是因为电脑上有几个版本的 Python 在打架吧。)不是什么大问题,创建了一个新的虚拟环境,重新装一下 Markdown 的库就又能跑了。又过了一阵子,生成 feed 的库里面有一行代码开始报错说「缺一个参数」。奇妙的是我这段时间根本没动过那写代码。
于是大过年的,决定用 Go 写了一个新的。其实还是有一些小问题的,比如 CSS 什么的。
上一版的 blog 生成器花了一星期。这一版的用了 3 天时间,但是实际写码的时间只有 11 个小时。中间用了很多 GitHub Copilot。
试图直接把一堆 Python 甩给 Copilot 让它「翻译」成 Go,但是它只是生成了一个简单的文件夹结构和一些并不重要的函数。
但是很多具体的功能,很多时候写个开头,一路按 tab 就行了。比如排序、regex、读写文件,都是它直接生成的。
该选哪些库也是 Copilot 教我的,比如用来解析 Markdown 的 goldmark,用来生成 feed 的 gorilla/feeds。这两个库实际用起来感觉也比 Python 的两个库更舒服。
而且我心想,既然都重写了,比如干脆加上语法高亮和 Mermaid 的支持,幸好 goldmark 的扩展都有现成的。
我之前一直用中文的楷体来表示强调,因为斜体汉字太难看了,手段是手动加 CSS。所以这次还试图写一个新的 goldmark 扩展,找个特殊符号,在解析的时候替换成 <span class="kai">。但是有点复杂,Copilot 提示的做法都不能用,直接跑去读 goldmark 的代码对照,好像 Copilot 生成的一些函数用法已经 deprecated 了。于是后来放弃了。
Go 本身写起来就挺舒服的,再加上 Copilot 的助推,整个过程相当 pleasant。不过,虽然确实需要检查生成的代码,看它是不是在做正确的事,但在脑袋里形不成什么深刻的印象。
最近想起来刘晓波曾经说过的「殖民三百年」,今天从网上找到了这样的出处,据说是 1988 年的采访:
金鐘是這麼問劉曉波的:「什麼條件下,中國才有可能實現一個真正的歷史變革呢?」劉曉波回答:「300年殖民地。香港100年殖民地變成今天這樣,中國那麼大,當然需要300年殖民地,才會變成今天香港這樣。300年夠不夠?我還有懷疑。」
1988 年看来,香港自然是一个发达的城市。然而移交之前,港英政府的政治架构是服务于殖民者的,其施政风格一直是「行政领衔」(executive-dominant),民主制约并不存在。总督兼任立法会主席,立法会一半议员是「官守议员」,由政府官员兼任。另一半「非官守议员」由总督任命。
香港移交之前,港英政府试图加大民主参与。但是大陆官方极力反对。
1997 年移交之后,香港政治机器服务于殖民者的性质是没有变的,只是宗主国从英国变成了中国而已。而秉承「专业精神」的施政团队,换了老板依然兢兢业业,娴熟地运用旧殖民者留下的行政和法律工具,服务新的殖民者。
比如说,雨伞运动、占中等示威期间,特区政府用来逮捕并公诉示威者的法律工具「公安条例」(Public Order Ordinance) 是 1967 年港英时代颁布的。
大陆政府没有信守「基本法」的承诺是确凿的事实。但港英政府没有向香港人赋予民主也是确凿的事实。
实际上,民主本来就不是「被赋予」的。且不论殖民主义这种剥削制度的利弊,幻想「被殖民三百年之后,就成为文明国家」是不成立的。只要是被殖民,三百年不行,八百年都不行。
自己的政治建设是要自己做的。
现在又开始试着用 Go 写一些小东西。于是买了一个 Web Development With Go 的教程。视频教程的标价是很贵的,于是犹豫不决。看来看去之时,翻到页面最下面,发现还有一个只卖电子书的选项,才 60 刀,于是果断下单。感觉这门课的主创真是定价的人才。
买书之前觉得其实不用任何教程,一边用 ChatGPT 一边看文档,照样可以做出自己想做的东西来。但实际做起来,才发现要收集、整理的信息是很庞杂的。自己通过不断试错、get your hands dirty 还挺花时间的。
而且有可能会犯自己意识不到的错误。
比如看这本书里的代码,发现他很 unorginal 地用了 MVC 架构。(但是 uoriginal 是有 unorginal 的好处的,就是整个东西会更 predictable 一些。)所有接触数据库的代码都在 models 里,数据库连接是在 main 函数里创建的。每次读写数据库,都是把数据库连接传到 models 函数里。数据库连接一直到程序退出才关闭。
然后想起两年多以前写的 Go,发现自己是在每次查询的时候,连接数据库、查询、关闭连接。每查询一次,就要这么折腾一下。当时怎么没意识到打开、关闭数据库是很 expensive 的。
当时还困惑,为什么每次打开某个页面,列出来的数据总是少开头的两行,有可能就是某次查询的时候数据库喘了……
看来这两年其实没白过吧。
应该是:
「乱了纲常」
记得 2015 年的一个周末,那时还在北京。一共四个人在西北三环的一家砂锅粥店吃饭,有 J 和 X,当然当时还有前妻。
年份和地点记得不是很确凿。说是 2015 年是因为记得当时还在 N 报社上班,之所以说是砂锅粥店,是因为 N 社旁边不远处有个同名砂锅粥店,我还蛮喜欢。(老板是潮汕人,早先还可以用比特币结账。) J 提出要吃饭问想去哪儿,我不明就里可能就提了这家店的名字。这次会面我总会想起,每次想起就查一下地图。西北三环那个犄角的内侧,一直有一家「蟹老宋」,并没有砂锅粥店的名字。但当时确实是在西北三环的那个犄角。
一边吃一边聊,J 问我那时都在通过什么渠道获取信息。我不明就里,直率地说,我正在「收缩」自己的信息摄取,越来越觉得新闻也好、公共事件也好,没什么关系。J 君语塞,我当时恐怕还蛮迟钝的,丝毫没有感觉到冷场。回家路上前妻告诉我,J 想和你聊,其实是看能不能把你挖过来。后来才知道 J 那时正在策划一个好友分享新闻链接的社交产品,产品形态有点像「即刻」。
之后不久,我从 N 社辞职。没做什么后面的打算,就是觉得不想再继续干下去了。用现在的话说可能是叫 burned out 加「政治性抑郁」。然而 that's not something I want to say, because that doesn't sound like something I would say. 一个原因是现在每天讲英语的时候,很多词尽管知道字面的意思,但如果不是确切知道 “how it cuts”,我是不想说的。另一个原因是对 N 社印在纸上的词感到可疑,对汉人知识界的一些词也时常感到有距离。
同一段时间,我的一个微信群里聚集了很多有趣的、年轻的朋友。虽然记不清对话发生的背景了,但是我记得跟朋友 M 有一次讲,感觉人生每一步都是在「逃跑」。
这种感觉一直持续了很多年。现在回想起来,之后经历的若干次更大的挫折,其实都可以追溯到那次砂锅粥谈话。但很奇怪,有一次问过前妻记不记得那次吃饭,再后来也问过 X 是不是记得这样一件事,两人都说毫无印象。
之所以又想起这件事,是因为上周或者上上周自己出去跑步,停下脚步的时候突然觉得此刻挺好。意识到自己已经有一阵子没觉得自己在「逃跑」或者「收缩」了。此刻 “I am”,自己在做的事情是 to be 或者说 être。这状态不是很好,但也不是很坏。是一个 state of being。