人们往往倾向于研究和创造表层的应用,而不是深入探索底层的原理。这并非对应用科学的偏见,而是因为表层工作更容易取得可见的成果,也更“炫酷”,更容易获得认可与回报。 从利益角度看,这种倾向其实十分自然。表层的事物,只要新颖,就容易被视为创新。除非强烈的个人兴趣或长期理想,在各种压力下,人们也通常会优先选择更容易产生成果的表层创新——即使具备更深入挖掘的能力。而对底层原理的研究往往只在两种情况下出现:1. 一个人或一群人不依赖外界反馈,完全出于兴趣、信念或理想去探底层原理,或预见到其巨大的潜在价值;2. 当表层创新逐渐遇到瓶颈,创新的难度已经接近底层突破的难度,或者表层创新受制于底层基础的发展,这可以被称为“应用驱动的创新”。如果把视角放到整个社会层面,规律依然类似。第一种情形可能更为常见;而第二种情况,则往往出现在一个领域的表层应用进入衰退期之后少部分人的坚守。底层原理的突破常常会引发表层应用的热潮,而表层工作的过热又会带来低效的繁荣和后续不可避免的消沉。从宏观上看,也就形成了一个领域在历史长河中的兴衰循环。 我们当然不能否认表层工作的“百花齐放”,它是孕育优秀成果的必要土壤,没有大量尝试,也不会有真正革新的应用出现。但从更长远的角度看,一个领域的理想状态,或许是底层创新与表层应用保持合理比例:无论通过有形的政策引导,还是无形的市场调节,让底层突破与表层创新交替出现、相互促进,才能让整体效率达到最优。从更大的时间尺度来看,即便没有刻意干预,人类社会的自然演进也会呈现出底层原理与表层应用交替发展的节奏。正因为无论底层还是表层创新都充满不确定性,我们无法完全预测它们的路径,于是只能任由热潮此起彼伏、周期往复。或许,这种“无序中的自洽”,正是现实世界的最优解。

最近我偶尔会想一个问题:那些小说作家是怎么写出那么长的小说的?这个问题最初源于我玩一个叫做《双影奇境》的游戏。这款游戏的开头设定很特别:每个主角都是作家,他们脑海中都有多个独立的小说虚拟世界,而这些虚拟世界正是他们创作的源泉,玩家也是在这些虚拟世界中展开冒险。 写一篇小说一定有很多困难。首先,如果我们想写一个比较长的故事,这个故事肯定会产生一些前后相互依赖或关联的情节。如果不小心处理,很可能出现前后不一致的情况。那么,实际上作家在创作小说时,是如何保证故事前后一致、连贯性的呢?我觉得,很可能的原因是:作家并不是在写完某些段落后,再去增加新的故事延续。而是他们在脑海中已经构建了一个虚拟的小说世界模型。在写作时,他们只需要让这个虚拟世界在脑海中“运行”,然后把世界中发生的故事以文字形式记录下来,就能形成小说。这种方法可以在最大程度上保证长篇小说的前后一致性和整体连贯性。 这种思路在我长期接触的计算机系统领域也有所印证。无论是磁盘存储还是程序在内存中保存运行状态,都涉及一个数据一致性的问题。比如,我在内存中保存软件的配置项时,如果为了方便或效率将同一个配置项存储在多个变量中,那么后续修改时可能因为疏忽只改了一份副本,就会导致同一配置项在内存中出现不一致的副本‘在存储系统中,如果相同或应该一致的信息在磁盘上存储了多份,即使形式不同,当操作这些磁盘的计算机断电或关机时,也可能因为数据副本不一致而破坏整个存储系统。在计算机领域,保证一致的方法就是原子的修改应该一致的状态,尽量减少关联数据的副本,尽量用重建表示的方式代替副本的形式。 这其实和写小说的思路很类似,如果我们完全依赖非常长的上下文来编写后续章节,很容易因为对某个事件的描述存在偏差而出现前后不一致,而且往往也难以回忆并检查这些不一致。随着故事篇幅增加,修正这些不一致的代价会成倍增长。因此,对于较长的小说,我们越不应该边写边构思后续情节,而是应该在最开始就把故事概要在脑海中梳理清楚,或者最好建立一个完整的小说世界模型,让故事在脑海中自然展开。我觉得这也应能解释为什么有些原作者之外的其他作者对一个经典小说进行续写时,他的反响往往不如原作。 说到长篇小说的创作,也不得不想到最近非常火的大语言模型。大模型擅长写小说吗? 大模型本质上就是一种生成式语言模型,它可以进行创作。有人猜测,这类模型在有限的参数中,可能已经压缩了人类的大量知识,甚至包括某种世界模型。因此,如果让大模型生成小说或长篇故事,它理应表现得不错。实际上,网上也有研究和论证表明,大模型确实可以创作出较为完整的小说作品。但是,按照我之前讨论的思路,要写出一个好的长篇小说,大模型不应该仅仅依赖已经生成的上下文去延续故事,而是需要有整体的构思。它应该根据最初的设定,结合自身对世界的理解,以及提示词(prompt),去构建一个虚拟的世界模型。 如果一个作家脑海中已经有了完整的虚拟世界模型,那么把这个模型“传递”给大模型并不容易。原因在于,对于一个复杂的虚拟世界,直接在脑海中“运行”它,比用语言去精确描述这个模型要容易得多。要把脑海中的复杂关系完全描述出来,所需的语言信息可能比写整部小说还要多。如果在输入过程中需要精确描述大量细节,就会产生极高的成本,这并不高效。所以,关键在于大模型自身的能力:它是否能够利用自身内在已经学习的世界知识,再结合提示词,构建出一个足够丰富的虚拟世界,从而生成连贯、有深度的小说内容。这种能力决定了它能否在生成小说时表现出像作家脑海中那样的整体连贯性和世界观深度。

“计算机学科的基础理论从根本上来说可以分为哪几个方向?” 这个问题我最近偶有新的思考,记录下来。首先看下 chatgpt 怎么说: 计算机学科的基础理论可以分为多个方向,主要包括以下几个方面: 计算理论:包括图灵机、可计算性理论、复杂性理论等,研究计算的本质和计算过程中的复杂性。 算法理论:研究算法的设计、分析和优化,包括算法的效率、最优性和应用问题。 数据结构:研究如何组织和存储数据,以便高效地进行访问和修改,常见的数据结构包括树、图、哈希表等。 自动机理论:涉及自动机的定义和性质,研究语言的识别和生成,相关内容包括形式语言、正则语言和上下文无关语言等。 逻辑与证明理论:研究计算机科学中的逻辑基础,包括命题逻辑、谓词逻辑和自动证明等。 编程语言理论:研究编程语言的设计、实现以及其语义和类型系统的理论基础。 计算机系统理论:关注计算机系统的结构和运行机制,包括操作系统、分布式系统和网络协议等。 以上每个方向都有其独特的研究问题和应用场景,构成了计算机科学的理论基础。 其次,国内的计算机专业也早就分了三个子学科,计算机系统结构、计算机软件与理论和计算机应用技术。 这些分类肯定各有道理,我先不去替他们解释,先记录下我的想法: 系统结构 系统架构:既包括计算机的硬件组成架构设计,也包括多个计算机组成的分布式系统设计。这里涉及到很多经典问题,包括容错、一致性、缓存系统、扩展性等等。 控制系统:既包括单个计算机的操作系统设计,也包括分布式系统中的控制节点设计。这里也会有很多经典的问题,比如调度公平与效率的权衡,资源碎片和利用率问题等等。 通信系统:包括计算机之间的网络通信架构和通信协议设计。通信协议分为多个层次,可以参考 OSI 模型。 编程语言 编程语言:人要将自己的语言转换为机器指令,设计介于人和机器间的编程语言必不可少的。 编译器:要把编程语言转成机器码,也就有了编译器这种特殊的软件。 软件工程 软件工程也许更多是与人相关的,一个成功软件也是一个成功的项目,项目的规模、生命周期、开发进程,都会相当重要。 计算机应用 不必多说,正是人们需要应用计算机,才有了计算机。一些热门的方向例如: 人工智能 互联网通信 科学计算 数据存储和数据挖掘 形成“闭环” 人们写了程序(软件工程),转换成了机器语言(编程语言),程序就以人们设计的方式(系统结构)运行于计算机上,这个运行的系统也就为人们提供了他们想要的各种服务(计算机应用)。因此,这四个研究方向”闭环“了:

Technically, KVM-based VM is a special type of virtual machine which relies on physical machine features. Following lists some popular VM types that do not use KVM. Hope you also find it interesting. VM Name Translation Technologies Executable Format Runtime Dalvik VM (Register based VM) Interpretation Android (<2.2, 2008) Dalvik VM JIT + Interpretation (Just […]

What is a “Container Runtime” ? As already explained in a previous blog (容器生态技术栈 – JciX ~), container runtimes are the components that will take the responsibility to run the container. They will be invoked by container engines (like containerd, and CRI-O), and will create the containers using Linux kernel primitives (like cgroups, and namespaces). […]

本文概述 HotCloud ’18 中的一篇讲云原生文件系统的论文,来回顾下存储领域大佬 Arpaci-Dusseau 在 6 年前对云原生文件系统的想法。论文链接 hotcloud18-paper-arpaci-dusseau.pdf (usenix.org) 文章的贡献主要有两点: 提出一些云原生文件系统所应该遵循的设计原则; 提出一种云原生文件系统 CNFS 的大概设计。 云原生文件系统的设计原则 作者把设计的原则分为存储和计算两个层次,但总体来讲都聚焦于成本和性能的权衡。这种权衡是云环境相对传统环境更容易做到的,也是云原生文件系统设计的核心。 存储原则 可靠性已经通过更底层的云存储服务得到保障。云存储比如对象存储 S3 或者块存储 EBS,已经提供了多副本等可靠性功能,因此云原生文件系统可以把这部分功能卸载到更底层的云存储。 云存储空间便宜且可以无限扩展。云原生文件系统的设计应该尽量利用这些便宜的存储空间对数据建立索引,用空间换时间。 云存储与本地存储有很大差异:带宽通常较高;延迟根据服务分级不同差异明显;更快分级的云存储访问成本反而更低。因此云原生文件系统应该按冷热层次化地放置数据,来兼顾成本和高性能。 CPU 原则 云上 A 个 CPU 计算 B 秒和 B 个 CPU 计算 A 秒(A * B = B * A)的成本相同。因此,云原生文件系统的计算任务应该尽量并行起来,这样可以在尽可能短的时间内完成任务。 类似于云存储的空间,云上的 CPU 数量也很容易扩展。云原生文件系统应该按需地使用 CPU,但也需要注意根据负载的变化对之前扩容的 CPU 数进行缩容,来控制成本。 由于云存储可以在计算节点间共享,可以适当的将与文件系统相关后台任务从计算节点分离出来,让计算节点的 CPU 资源更多地用于计算任务。 云服务中 […]

MinIO 是一个用 Golang 编写的对象存储 server 开源实现。s3fs 是一个基于 FUSE 框架的以 s3 存储服务作为后端并导出 POSIX 文件系统挂载的开源实现。 本文首先基于 MinIO 搭建一个简单的对象存储服务。然后进一步借助 s3fs 将这个对象存储服务挂载为一个文件系统目录。 搭建 MinIO 对象存储 安装 Minio go install github.com/minio/minio@latest 启动 mkdir minio_dir minio server minio_dir CLI 操作 curl https://dl.min.io/client/mc/release/linux-amd64/mc \ –create-dirs \ -o $HOME/minio-binaries/mc chmod +x $HOME/minio-binaries/mc export PATH=$PATH:$HOME/minio-binaries/ # 设置 alias,之后就可以将 myminio 作为第一级目录操作了 mc alias set myminio […]

本文以我的视角对 ublk 进行了最基本的分析,希望也为你带来帮助。 ublk ublk 是一个 6.X 内核全新的实现用户态块设备驱动的内核框架,之前的类似框架还有 TCMU、vdpa-user (VDUSE) 和 NBD。ublk 框架中,一个额外的 ublk Server 用户态进程作为 ublk 块设备的服务后端,实现了主要的存储逻辑。区别于其他用户态块设备框架,ublk 采用 io_uring 作为内核与用户态通信的传输机制。ublk 架构图如下: 使用 ublk 框架,内核会多出几种设备,包括一个唯一的 ublk_ctl 设备,多个名为 /dev/ublkcN 的字符设备,以及同样数量的 /dev/ublkbN 块设备。其中, 块设备是实际的存储服务设备,可以格式化文件系统或者作为裸设备使用,这也是 ublk 存在的最终目的; 字符设备是 ublk 框架的数据面接口,主要被用户态 ublk Server 进程用于与内核通信,处理块设备的实际 IO 请求; ublk_ctl 设备(/dev/ublk-control)则可以看作的是 ublk 框架的控制面通道,ublk Server 通过请求 ublk_ctl 设备来创建出多对字符设备和块设备, 类似于其他用户态驱动框架,ublk 为了方便用户态 ublk-server 的开发,也提供了用户态 SDK […]