Mobile / Web 软件开发者@Thoughtworks.com
- 在读:《盲人钟表匠》;《理性思考的艺术》
- 在玩:《塞尔达: 王国之泪》;《黑神话:悟空》;《博德之门 3》
- 在练:推 85KG * 7 * 5;蹲 135KG * 7 * 5;拉 120KG * 8 * 5
Mobile / Web 软件开发者@Thoughtworks.com
这周对日常工作流中使用率占比相当重的 Raycast 进行了一些设置修改。 起因是 Raycast 订阅过期了,在订阅过期两周前收到邮件说现在续费就给 20% 优惠,但想了想没必要续费。Raycast 提供的 AI 功能我主要用来翻译,语法纠正和润色,chat 极少使用,尽管其启动成本和 chatGPT for mac 一样低。 学习双拼 chat 好办,直接切换到 chatGPT。可能是因为新鲜感,和 AI 聊天次数多了不少,突然萌生了应该提高自己打字速度以减少“使用 AI 解决问题”的心智启动成本和更强的“为 AI 提供充足上下文”的意愿。 说学就学,简单调查之后选择了小鹤双拼。想知道熟练使用双拼之后,打字速度能提升多少,所以还做了个全拼和双拼的速度测试对比。(测试地址 https://dazi.kukuw.com)  现在看起来惨不忍睹,双拼一分钟只能打 18 个字,希望两周后能和全拼差不多。 社区插件代替订阅 但「用预设 prompt 处理选中的文本后再填充到输入框」这活儿依然是 Raycast 最快。调查了一下发现可以用 Deepseek Quick Actions 和 Google Gemini 社区插件填自己的 key 来代替。 尝试了一下发现尽管 Gemini 的 Key 有免费版可以使用,且速度极快但失败率实在太高了。而 deepseek v3 速度虽然有点慢(和 raycast AI 差不多但不如 Gemini),但稳定且便宜,几天用了一百来次不过 2 毛钱。 产出 用 Alex for Xcode 以 vibe coding 的方式开启了一个 side project,非常好用!后面有空单独写一下。 ...
这周主要工作在重构上。之前有两个高度重合模块需求出来的时间间隔有点大,且过程中产品和开发沟通不足,导致两个模块实现过程中产生了不少冗余代码。 这种时候 code diff / PR review 经常发现,core contributor 们在重构议题上有很强的「技术卓越」倾向,同时当可扩展性和可维护性两个词搬出来时,很难从技术角度说是错的,然后大家陷入一轮又一轮的争论。 考虑到这两个特质在复杂业务项目中实现的成本,以及过往太多实现了高可复用模块但并未发挥作用的经历。个人感觉其实更好的做法先放下技术人视角,和干系人(老板)沟通,确认真实的验收标准,严格执行,交付,然后开始进入下一个任务。 把这个反馈循环牢记于心,一方面可以节约大量不必要的讨论精力和实现成本,另一方面也可以避免出现明明花费了大量时间精力,但老板不认可成果的情况出现。
近半年都在进行 redesign 相关的工作,除了 UI 从 UIKit 切换到 SwiftUI,还有网络层的切换,从 restful 切换到 GraphQL。因为六月份就要上线,现在就开始进行后端联调及各种功能的集成。即使团队已经很“敏捷”,有各种沟通对齐的会议,但到了这种时候也会发现有很多可以改进的事项: 跨功能模块的需求,因为沟通问题,到集成的时候才发现没有人负责 完成较快的模块,团队成员出现空转,等着集成,但集成的时候又发现其实有功能缺失 个人认为是因为很多团队成员都在远程办公导致线上对齐会议参与度不高造成的,但感觉很难让大家都在会议中全程投入精力去了解别人在干什么,一般都更新完自己的就,就开始做其他事情了。 产出 和设计师朋友喵喵聊了聊自己想到的几个 side project 的主意,其中一个被选中了。对方很快就做出了设计稿,希望可以在闲暇时间做一下试试看。 娱乐 《塞尔达:王国之泪》 通勤路地铁里就会打开玩一玩,40 分钟逛几个神庙探索一小块地区就会觉得很开心。 《搏击俱乐部》 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 时隔数年再看一次,还是很喜欢。比如片尾插入的几帧 nice big cock 这个事儿,就感觉很酷。但以前主要是看像狮子一样的布拉德·皮特,现在是看爱德华·诺顿的表演。 《阳光灿烂的日子》 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 小时候看觉得大院儿生活也太棒了,现在看感觉很燥热,而且发现姜文拍片很喜欢同一个事情给很多重复镜头,比如夏雨拿着望远镜转圈,在屋顶来回爬。在《让子弹飞》里也是,让马车拉着枪来回跑,重复镜头很多很多,个人感觉会容易累。不过宁静依然和记忆中一样好看。 《诡才之道》 ⭐️ ⭐️ 题材相当好,从鬼的视角来讲如何吓人的。比如闹鬼的时候,鬼是如何让灯光不停闪烁,是如何让人打不开原本可以打开的门的。但当设定讲完了之后,导演就想讲个青春期女生在鬼友帮助下如何成长的励志故事了,一下落得相当俗套。
本周工作产出主要是准备 showcase 及修复 iOS 15 UIHostingViewController 在 UINavigationController 层级下可能会出现 navigation bar 无法隐藏的问题。 输入 《盲人钟表匠》 当人们走在路上如果看到一块构造奇怪的石头,无论其构造如何诡异,依然会有概率相信这样一块石头是自然产物。但如果在路上捡到了一块钟表,则极难让人相信,这是自然产物,原因在于钟表的复杂性。那么相比起身体构造,钟表的精细程度显然不值一提,也就很难相信人是自然产物,而不是神刻意制造出来的。 《盲人钟表匠》 这本书就是讲进化论的自然选择,是如何反驳这个在达尔文出现之前,最有影响力的支持”上帝存在“的论证——「设计论证」。 娱乐 《辐射》 ⭐️ ⭐️ ⭐️ ⭐️ 剧情一般,没能把各种避难所的荒诞以及地面各势力的斗争体完全体现出来。但场景道具服装还原极佳!再玩一次辐射 4 是不可能了,但很期待新辐射。 《苦尽柑来遇见你》 本来对韩剧不太感兴趣,但时间线上看到太多人说好,开始看看。
突然得到消息需要为 CTO 准备 showcase,后来得知发布日期的改变和 showcase 都是因为项目合同可能会出现一些变化,所以是工作比较紧凑的一周。 周末小朋友被他外公外婆带出去玩了,得了两天空闲。研究了一下如何更好地利用懒猫微服 NAS。但因为自己对数据安全的敏感,不太乐意往里面装不清楚来历的东西,而自己又嫌弃麻烦所以也没有太多成果,甚至开始思考这个东西到底是否适合自己了。 输入 《Tiny Experiences》 又一次受到 cbvivi 的影响,看他在读《Tiny Experiences》这本书,发起了一个要连续更新博客一百天的活动。这本书我只看了开头,个人感觉核心概念和但行好事莫问前程很像。先用一个契约把事儿做了,做的过程中自然会有好事发生(量变引起质变)。 同时相当喜欢 cbvivi 在这篇博客最后面的引用: When you write, you think better. When you think better, you create better. 娱乐 《塞尔达:王国之泪》 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 周日硬生生玩了十个小时,把地底的很大一片区域都探索了,获得了一套衣服。期间没有一分钟不是开心的。 《白莲花度假村》第一季 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 很戏剧的一部短剧。值得一提的是其中一个主演是《Why Women Kill》的达达里奥,漂亮的眼睛颜色让人感觉她又不知所措但又带了一些神经质。
因为被要求做一个优先级很高的任务,所以这周很舒服,统计的工作时间有一半都专注于代码。 娱乐 《塞尔达:王国之泪》 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 王国之泪刚刚发售的时候就购入了一台 NS oled,但对它投入的时间其实远不如前作荒野之息。在看本周 NS 2 的发布会时。产生了强烈的购买欲望,但稍微冷静之后,就觉得这台 NS oled 并没有物尽其用。顺便趁着上周去九寨沟回忆起来了许多玩荒野之息时候的快乐时光,又把王国之泪捡了起来,玩了相当开心的 3 个小时。 《黑镜》第七季 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 一共 6 集,很喜欢讲妻子受伤后被迫上传大脑到服务器,结果陷入订阅服务陷阱的第一集。和第五集,通过回溯照片解除自己去世前任误会。 《让子弹飞》⭐️ ⭐️ ⭐️ ⭐️ 重看了一次,前半部分一如既往的好看,但最后半小时节奏太拖拉了。
清明节去九寨沟玩了一趟。 小学时候和妈妈去过一次,还记得周围大人都穿着厚厚的衣服,但自己穿着短袖尽管冷得哆嗦,可听着旁人说“你看这个小伙子身体真好”,又觉得得意的场景。 景点也只记得一个五色海,当时同行有位大叔还问导游:“这水能不能喝?”,导游顿了顿答:“别喝太多”。 现在再看到这个景点,感觉已经和记忆中完全不同,连印象中的大叔和导游也无处安置了。 而且看到这样有山有树的地方,会立刻联想到几年前操纵着林克爬山滑翔的场景,进而想起当时玩荒野之息的愉快体验。相比玩了数倍时长于荒野之息的一款开放世界手游,却几乎不能让我在现实生活中产生共鸣。 想来或许和游戏制作人的目的有关,手游心思花在设计各种刺激点来让人氪金,游戏内容本身更像是吸引玩家入门的东西。但单机游戏则就是以做出好的游戏内容为主要目标。 Input 本周没有太多输入和产出,但在高铁上舒舒服服地看完了一本小说。 《恶意》 ⭐️⭐️⭐️⭐️⭐️ 东野圭吾的侦探小说阅读体验一直都很好。看到最后才会意识到开头的性格描写产生的印象会有多深刻,第一印象确实很重要啊。
眼馋了朋友的 NAS 已久,自己调研了 4 个小时之后,机缘巧合之下,在 x.com 上通过懒猫微服创始人 Andy Stewart,得到了一张优惠券购入了这个看起来蛮贵的机器。 但目前仅仅是用来同步照片及网盘,还没有发掘其全部的功能。饶是如此也能在未来节约每个月 68 块钱的 iCloud 税。 Input 听 《Cortex》 主播之一 Myke 将要生小孩,Grey 推荐了几本书,被其中一本《Selfish Reasons to Have More Kids》 给吸引了。大家聊起生更多小孩这事时,通常都和社会福祉挂钩一起聊,但个人聊到这个话题时,一般会咂舌说「一个都够受了,哪敢要要多的」。那有什么站的住脚的「自私」理由应该多要一些小孩呢?
工作时间只有 35% 写代码,其他的时间要不然是在会议上,要不然是各个群里灌水了,自觉状态不是很好。 这时候会想起来上个项目共事的同事 Lin。客户对他的评价就是——天生的领导者。对此的理解是,因为他对于自己工作专业态度的一致性,以至于同组的成员很容易就受到他的影响,整个团队的工作效率也被拔高。 脑子里立刻能回忆起来的就有: Code Diff 及开会基本上会合上电脑,认真听他人发言,且与发言人产生互动 Slack 中对于团队内部及跨团队交流非常及时 承接任务之后会持续保持后续更新,符合「件件有着落,事事有回音」的标准 开始尝试着在自觉工作不在状态时想一下,如果是 Lin 的话,他现在会怎么做呢? Input Model Context Protocol (MCP) Mattt 写的一篇介绍 MCP 到底解决什么问题以及如何运作的文章,例子相当通俗易懂。 The most interesting people DHH 所写的「到底为什么要有一个小孩」。举了一个自己很喜欢的例子。当有了自己的小孩之后,就像是得到了一个机会可以观看世界上最有趣的人的演出一般。这场演出极其精彩,但作为父母你并没有办法说服其他人和你有相同的感受。有小孩之前,我应该是无法理解这种比喻的。
周一一大早发现 Github Copilot license 申请下来之后就迫不及待开始在项目上体验了。尽管之前在自己的 side project 上使用过,但在澳洲最大的流媒体应用这个量级的项目上,还是头一遭。 先说结论,目前个人感觉对生产代码的编写提速帮助不算大,但通过 chat 来了解代码结构及技术决策分析会有奇效。 因为日常工作中,需求分析及 Tasking 的时间占 80%,实际写代码的时间可能只有 20%。此前还和同事打趣,写完了 issue 文档基本上等于代码都写完了。所以现在有了一个具有整个 codebase 上下文的 AI 来辅助阅读及理解代码,整体速率的提升还是比较明显。  但在如此复杂的项目结构及复杂业务上下文的场景下,如果想要通过 Copilot Edits 帮助实现代码,就需要把指令拆分得非常小且明确。即使如此也还是要经过很多轮的验证。有这个时间,自己写早就写完了。 娱乐 杀手寓言 ⭐️⭐️ 因为在社交媒体上看到了该片很酷的动作场景片段才看的电影,但实际上体验是:搞笑梗很烂,情节俗套且拖沓。剧情发展从头到尾没有一丝丝意外。精神不正常的角色都演得不错,但太多了,是个反叛就神经质,导致同质化比较严重,就审美疲劳了。 一分给动作场景,一分给变态反派们。
上周写完自己对于 AI 可能产生的对程序员这个职业的影响之后,无独有偶,好几个程序员朋友也和我聊起了这个话题。看起来大家都有相关的顾虑和想法。有个好消息是,由于我一直在做咨询交付类的项目,所以在使用任何 AI 之前都需要客户的同意,但因为知识产权的关系,使用 AI 辅助编程很难推进,只能自己脱敏之后通过 chat 的方式来运用。但最近的项目客户已经同意在接下来的工作中使用 AI 辅助的 IDE 来进行日常交付了,这下或许可以深度感受到 AI 给职业带来的影响了。 因为去了一趟日本(4 天),所以没有太多的工作产出或是输出,不过在秋叶原见了一些市面,甚至产生了如果国内有这样的地方和文化,自己努力赚钱的意愿会更强的想法。 输入 《正面管教》 ⭐️⭐️⭐️⭐️⭐️ 很多可实操的和小朋友相处的技巧及原理解释。落笔此刻印象深刻的就有: 为什么制定规则之后孩子会产生反叛行为 大人如何教育孩子承担自己的责任 发生分歧时,如何展示出对事态的尊重 虽然是教育小孩的书,但其中很多的方法和道理对于成年人之间相处也非常适用。 《第七天》 ⭐️⭐️⭐️⭐️⭐️ 尽管故事的时事感太强(医疗事故,火灾,食品安全),导致有点出戏。但看到描述铁道工人父亲的部分,也让我看得差点哭出来。其中很多父子相处的描述都和自己记忆中父亲独自照顾年幼的我极其相似。同时在看到主角被父亲放在石头上坐着晃荡着双脚的时候也会想起自己的儿子。 如果真的有这么一个死无葬身之地,我的父亲应该会在那里等着我吧。很想他。 娱乐 长发公主 ⭐️⭐️⭐️⭐️ 中规中矩的迪士尼公主,特殊之处在于男主角较为不同寻常,是个小偷。
工作 算是在 deadline 驱动下,度过了生产力爆棚的一周(请了一天假),每天实际写代码的时间达到了 7 小时。究其原因,只因为老板说有个新的提案要做时,加了一句“I personally think you are the best to work on it”,就卯足了劲儿赶在他需要的时间前,把手上的工作都快速处理好了。我真是容易满足啊 🫠 输出 周末花了点时间写了两篇博客 DateFormatter 静态实例的一个小坑 面向用户的版本号 在写《面向用户的版本号》时,想起几年前曾有一个想法——编写一个系列,帮助非技术背景的 PM、BA、UX 或相关干系人理解移动开发领域的技术选型差异可能带来的业务影响,比如《移动开发中实现 Deep Linking 的 URL Scheme 和 Universal Links 的区别是什么?》这篇文章。 现在这种文章存在的意义似乎没有了,通过 AI 就能够图(mermaid)文并茂解释得更好,且有足够的耐心来解答读者的任何疑虑。可话又说回来,非技术背景的人在不知道有哪些技术方案可能会造成差异的情况下,是无法提出这样的问题的。 这就是我认为程序员这个工种短时间内无法被取代的原因:你没办法让 AI 帮助完成你不知道你不知道的任务。 即使在有 AI 加持的现在,依然需要具备相当多的软件开发知识,才能够在众多方案中甄别出相对合理的方案,由此从生产到部署再到维护,完成一个复杂系统的构建。诚然,学习能力足够强的人可以通过边做边学的方式来让 AI 构建,但走完了整个流程的他,其实已经通过 AI 帮助,在“做中学”的过程中成为了一个 AI 时代的程序员。 AI 时代的程序员:明白各种软件开发领域名词背后的含义,但并不需要自己去实现的人。 这种“做中学”产生的副作用(掌握软件开发知识),也并不是每个需要发布软件的人都想要的,因为它相当费神耗时,所以我依然认为程序员这个工种在“将想法变成现实”的路上,具有较高程度的不可替代性。 而 “工作的可被 AI 替代性” 这条线再具体一些,就是工作的产出物是否具有易于描述的创造流程,以及清晰的验收标准。输入和输出越复杂,描述和验收所需要的知识越多,工作就越不可被替代。 娱乐 玩了两小时《双人成行》,开始觉得尽管画面好看,游戏体验也不错,有很多的小巧思。但不会产生沉迷的感觉,说放下就放下了,甚至会产生玩了两个场景就有点疲了的感觉。当然再拿起来也没有什么负担。
问题 目前开发的 app 主要服务于澳洲用户,开发团队由中澳两地开发人员组成,所以写和 DateFormatter 相关测试时,通常会指定 Calendar 所处时区。否则可能出现测试在本地运行完美通过,但澳洲同事本地或者 CI 上挂掉的情况出现。 var mockCalendar = Calendar(identifier: .iso8601) let mockDate = mockCalendar.date( from: DateComponents(year: 2025, month: 3, day: 2, hour: 12) )! // 如果跑测试时候的时区是 Australia/Sydney,那么生成的日期是 02 Mar 09:00 #expect(humanizedDate(date: mockDate) == "02 Mar 12:00”) // ❌ 要解决这个问题,通过指定 Calendar 及 DateFormatter 的时区为同一时区即可。 var mockCalendar = Calendar(identifier: .iso8601) + mockCalendar.timeZone = TimeZone(identifier: "Australia/Sydney")! let formatter = DateFormatter() + formatter.dateFormat.timeZone = mockCalendar.timeZone let mockDate = mockCalendar.date( from: DateComponents(year: 2025, month: 3, day: 2, hour: 12) )! #expect(humanizedDate(date: mockDate, formatter: formatter) == "02 Mar 12:00”) // ✅ 优化 但在生产代码中考虑到 DateFormatter 在使用的时候如果不重用实例,则会额外耗费十几倍的时间。 ...
日常开发接触能接触到的版本号方案通常就是语义化版本(构建号版本): 语义化版本大致是:主版本号.次版本号.修订号(1.2.3)。 主版本号(Major):有不向后兼容的 API 更改或重大功能更新时递增。 次版本号(Minor):有新功能但仍保持向后兼容时递增。 修订号(Patch):当软件进行向后兼容的问题修复时递增。 构建号更简单,每次构建时自动递增。通常是团队内部用来定位问题使用,外部不可见。 今天偶然发现了用了好几年的日记 app Day one 的版本号,感觉还挺有意思,格式就是:年.当年发布次数。 软件的更新频率在很大程度上影响用户是否愿意投入时间和金钱使用该软件。相比常见的语义化版本号,这种版本号显然更用户友好。 ps: 是的,Day one 的更新历史中有个 2025.1.1。个人猜测或许是因为那次的更新只是一次非常简单的 bug fix,所以团队并不想将其作为“一次发布”记录在案。: ]
这周在日常使用 AI 时产生了两次印象比较深刻的场景。 在家用办公的时候用闲鱼买来的二手 Odyssey G7 显示器发现很卡,一度怀疑是 Mac mini M4 带不动。调整了很多设置都无法解决,问了一下 AI 提示可能是线的问题,结果发现果然是这样。 玩游戏的时候有一个地方卡住了,向 AI 描述了一下自己在玩的哪款游戏当前的场景是什么,马上就给出了解体方法。产生了一种,游戏攻略网站应该日子不太好过的想法。但话又说回来,如果内容创作者都日子不好过了,高质量的内容产出减少,AI 的学习素材也会受到影响。这是否会形成一种恶性循环? 工作 主要是处理一些前后端数据 mapping 相关的工作。为时间相关的展示业务逻辑添加测试的时候遇到了一个时区转换的“坑”,如果周末有时间准备写一篇博客来记录一下写了一篇博客来记录《DateFormatter 静态实例的一个小坑》。 娱乐 开始玩 《双人成行》,感觉有相当多的巧思在里面,且很适合一边聊天一边游玩。