对浙江杭州的千岛湖进行了两日游,简单分享下攻略。

  1. 如果对鱼头坐船有感情,可以体验下。
  2. 如果想看好风景,以及看群山,请避坑。建议去威海

怀着沉重的心情,还是开始落笔写年终了,相比很多人迟了 2 个月。
这一年发生了不少事,感觉清晰可见,又像梦一样不知哪里谈起。离职、旅游、待业、润,每一步都在计划之内逐步落地,但每一步都如履薄冰、心有恐惧。
人生中已经有很多重大变动,中考、高考、结婚生子、择业、多次工作变更等,现在回头看每一次都是巨大的转折。但当初处于那些时刻的时候,并没感觉到刻骨铭心。
而现在,年过三十、拖家带小的我,依旧在努力的尝试着重大的拐点突破,但底气不是很足。

记得中考时候很清楚历史和政治两门考的非常糟糕 (加起来都没到 100 分),很清楚弱小的身体没啥体育加分,但考试结束后就在田埂上无忧无虑的瞎转悠。
中考能升的高中只有两个,要么 “一中”,要么 “二中”。这两所高中是天壤之别,一个是继续上大学,一个是大专或者打工就业。

记得高考结束后傻乎乎的二指禅敲键盘,在网吧里通宵玩着飞车和农场。不知道 985/211,也不知道专业、就业、指南。填志愿一把梭哈,只因为里面有 “计算机” 三个字。
那时候以为终于离开了地狱,谁成想那是最后一次无忧无虑的天堂。
当时,只知道家人、老师、同学一起塑造的氛围,是一场 0 或者 1 的战役。但要说黑灯瞎火的努力是为了什么,不知道!
都没坐过电梯与公交,也没坐过马桶。我可不知道 “书中自有黄金屋” 里的 黄金屋 意味着什么,有饭能吃饱不饿,天塌下来有爸妈。

一直有一个写字痛点,就是错别字。尤其在发帖子和写文章这样的正式场合,错别字会引起很大的误解,而每次检查都会很吃力。
试用了人气较高的 “写作猫” 和 “火龙果” 两个纠错平台,都有很大的局限性,并不适合我这样的人使用。

写作猫的缺点是 word 走天下,一点也不 nice。
火龙果的缺点是没有纠错能力,我用测试文档只检测出来两个不存在的英文错误。
它们都不支持 markdown 检测。
付费较高,对于非高频使用人员不友好。

于是,尝试自己写一个纠错工具,目前做了开源,支持 CLI 和 GUI,详见:HLVSentenceHLVZhCorrect
技术方案是:检测文本文件 -> 文本分句 -> 词语检测 -> 工具集成
遇到的核心问题有:

  • 准确识别文本文件。文本文件无 Magic Number 二进制特征,如何准确识别当前文件为文本文件并读取内容。
  • 文本分句校准。对于纯中文场景,通过常用的标点符号即可正则分句。但一般会参杂英文、特殊符号,还有 markdown。
  • 中文纠错检测和校准。找了不少方案,最后选择 pycorrector 提供的中文纠错模型。工具需要和 python 环境做对接,并对待检测文本做进一步校准以满足模型。
  • 非终端环境和 python 脚本互联。需要支持 python 虚拟安装环境。
  • SwiftUI 开发 “命令行 CLI 工具” 和 “Mac 菜单栏工具”,将工具对接 brew 平台。

下面是开发文本纠错工具的一些历程。

只要使用电子产品,每时每刻都在和字符打交道。目之所及的字符,在存储、显示、执行等环节都离不开编码的支持。
但对于字符编码,也会有一些误区,比如:Unicode 和 UTF 是否都是编码、字节和编码的关系、āáǎà 的音标字符表达、内存字符编码 等等。

本文将循序渐进的,从 ASCII/ Unicode 介绍到 UTF8/16/32,以及文本二进制存储和 URL 编码 / 多次编码等场景,最后解释内存中字符串的编码格式。
每个环节都通过二进制调试的方式给予实际的场景输出,争取一遍将编码吃透。

函数调用栈虽然表面意思很容易理解,但是说到汇编层面,对于 call、ret 等命令的具体表现,还是有一些理解复杂度。
尤其在协程大放异彩后,通过函数调用栈来表达协程的逻辑,也尤为重要。
本篇文章会从基础汇编的角度理解函数调用过程,并给出有栈协程的汇编实现。这样会对诸多高级语言的协程有进一步理解。

在 OC 时代,通过 .h 头文件以及 include 标记,还有那长长的 api 名称,可以很方便的意会和找到某个类。使用 Xcode 十年,在 Vim 的加持下,基本没用过啥快捷键。
最近在 Swift 里面一顿拾掇,理解源码也太复杂了。
1 个 class 在 3 个文件中增加了 5 个扩展并实现了 4 个协议,1 个文件中包含 400 行注释 500 行代码 10 多个杂七杂八的 enum/struct/class/extension/protocol,去他妈的。

一直都是夸奖 Swift 的,作为后现代语言,集百家长补百家短。
但不好的编程习惯对 Swift 来说会是灾难,文件名不在作为当前文件内容的强约束、无需 import 后的 extension 可以写在任意位置、enum/struct/class 是值类型值语义引用类型引用语义搞不愣清后的混用,等等,这些都会骤然增加 Swift 源码的理解。

不得已对 Xcode 进行一些调教。
目标是快速查阅继承、搜索、实现协议方、三方库文档等代码阅读操作。

Swift Package Manager (SPM) 已经被苹果放置于一个很重要的位置,在历史文章中对其做了一定的分析,Package 目前的定位和 Xcode Project .xcodeproj 同级别。SPM 不仅仅用于替代 Cocoapods,而是 Apple 后期语言研发生态的一部分。
鉴于 Xcode 对 Package 的支持,可以很方便的将项目中的代码进行组件化设计,做一定的逻辑分析即可拆分成多个 Package,这在开发过程中非常有利于项目的架构、单测、可持续性。
以前若这样做,需要对 Cocoapods 有深入的了解,这是一个比较复杂且细节的过程。通过 SPM 只需要 New - Package 即可,将复杂度从项目级别压缩到文件级别。

SPM 出现后,很多 Pods 模块通过增加 Package.swift 配置文件可以很方便交由 SPM 管理。但对于直接通过 Package.swift 创建的独立库,并没有方便的方案转为 Pods 管理,还是需要走一遍 Pods 的流程。
不过,这里做一个预言,Pods 终将被 SPM 取代,因为 SPM 是更具有可持续性和生态深度耦合,在 Xcode 整合 (编辑 / 搜索 / 联调等)、多平台兼容,源码管理、二进制库 / 仓库管理、CI 等方面,都具有得天独厚的优势。
相比 Pods 完善的脚本自定义能力 (基于 ruby 的生态),SPM 是有一定的短板,但不推荐。
很多大公司在做统一基建的时候,会深度魔改 Pods。简单的东西越做越复杂的原因,除了增加一些” 又不是不能用” 的功能,还有就是在复杂度提升后打的各种补丁。
虽然这么说,Pods 完善的自定义能力,SPM 也一样可以做到,毕竟这些能力很大部分都属于扩展能力,如插件。执行流程中大家都可以在 xcodebuild 等相关命令的任意位置,随时可以写一些定制脚本做插入执行。

初期,Swift Package 只能做源码 (开源) 共享,后面增加了 binaryTarget 能力,可以在提供了二进制库 (framework/xcframework) 的情况下,直接通过 SPM 做分发。(闭源共享)
但二进制库从哪里来,普遍的方案还是通过 .xcodeproj 的形式编译导出 framework/xcframework 库。
Swift Package 虽然支持导出动态库和静态库,但流程上还不彻底,并不能直接交付使用,下面对此做一些解释说明。

最喜爱 世界之窗,那个快如闪电的 Browser。

每个人都有自己喜欢的浏览器,但每个人都不满意自己喜欢的浏览器。这是当今 Browser 之乱现象。
归根结底,在于浏览器内核太过复杂,没有推倒革新的可能。只能依托 webkit/blink 内核之上做层层补补的体感优化。
但千人千面,一个浏览器能够适配多个人的使用习惯已经很困难,更何况兼容上亿用户的心情。

也属实没想到,在早已过了 Browser 大拼杀的今天,还有 Arc 这样的黑马闯了出来。
已经重度使用两月有余,忍不住做一下使用过程中的体验和分享。

Arc 使用的还是 Chrome-Blink 内核,重在用户使用体感上的创新。
早期通过会员邀请制预约排号(目前已经完全开放),当时体验了半小时有余,放弃了,感觉不到又什么亮点。重新尝试后,发现了很多亮点。
应该还是使用的多了,就发现了很多早期没有注意到的功能。也侧面反映一个点,一开始使用有可能劝退。
希望分享可以降低初次使用的劝退门槛。
但也如开头所言,可能您最后并不喜欢也不选择 Arc,概率或许还很大。

不推荐使用 Swift 写脚本,和 Python 比起来,该生态链相对匮乏,开发耗时会增加很多。
但对于偏 Swift 的同学来说,这也的确是更可控和方便维护的方式之一。尤其对于公司内部工具,有问题可以更快的找到原因并处理,不至于手忙脚乱。

通过 Swift 进行脚本开发的环境和入门,可参考:Swift 脚本开发环境搭建

在开发脚本的时候,经常会使用到在终端环境中安装 / 预制的命令、管道、文件读取等。这些能力,SwiftShell 做了完备的封装,很方便使用。
这里对该库源码进行一些解读。同时,也会做前置知识点如文件、管道、描述符、子进程进行简单介绍。

2024.01.06 更:欢迎查阅 Swift 开发的文本纠错命令行工具

不推荐使用 Swift 写脚本,和 Python 比起来,该生态链相对匮乏,开发耗时会增加很多。
但对于偏 Swift 的同学来说,这也的确是更可控和方便维护的方式之一。尤其对于公司内部工具,有问题可以更快的找到原因并处理,不至于手忙脚乱。

相对于 Python 环境丰富的基建资源,使用 Swift 做脚本开发的优点在于生态的一致性
苹果官方抹平了 脚本开发 和 应用开发 的界限,即 开发环境、三方库导入和使用 (苹果自身的开源库 / 三方库)、系统平台 api (存储、网络、协程、并发等,UI api 除外) 等,均表现一致。
可以像应用开发的流程一样,进行脚本命令行的开发。

0%