2025

  1. 技术本质

    这篇文章是一片“解构与重组”的文章,解构的对象,可能是技术,也可能是我自己。 不论如何,我不想让任何阅读者在阅读的时候有太多的心理负担,包括我自己。 所以在此之前,我需要对自己做一个简单的结构,以此做为文章的起点,以确保接下来的文章内容能被阅读者简单明了的理解。 但我写作的风格是跳脱的,我不能确保文章上下文具有常理,哪怕对我来说,是的,它有常理。但这种常理并不适用于所有人。

    首先我是一个记忆力很差的人,这点不是自我贬低,我也从来没有觉得这有什么不好(除了应试教育,但这已经是过去式了)。 而我之所以强调这点,是因为这个基因给我的思维方式带来了巨大的影响。 因为我无法记住精确的信息,因此长期依赖我形成了一种思维习惯,那就是用解构替代记忆:将记忆分解成更多细碎的模式,在需要的回忆的时候,将这些细碎的模式重新组合成记忆本身。而模式本身也是一种记忆,或者某种感受。 但这种分解是有严重的损耗的,特别是遇到复杂的事物,比如人心。也就意味着这种损耗会让我无视掉很多当下重要的信息,但同时,正如内耗无处不在,这些损耗从概率上来说正好抵消了内耗带来的影响,可以让我发现事物底层的脉络。 这并不是说我拥有了预知未来的能力,相反的,这让我客观的意识到未来是不可预知的。 但我不想把篇幅过多的放在“解释为什么”上面,我只想提出一些结论,大部分情况下这些结论只适用于这篇文章的目的短暂存在。 当下的 AI 技术,本质上是一个没有记忆的东西,哪怕它用了巨量的数据去训练。所以我很能感同身受,它所谓的智慧涌现,到底是一个什么玩意儿。

    但不论如何,AI 是一次新的工业革命,它势必会替代人类的工作,也必然会替代人类工作。 但这是一个过程,不是一蹴而就,在这个过程中,政府需要解决人类资源的分配问题。 目前,大部分人使用工作来进行分配,少部分人使用资源来进行分配。 但我说过,我无法确切地预知未来,本质是因为少部分人或者说是少部分利益主体在主导着世界的进程。 也就是说,未来是依赖于什么来分配,这点其实还是有很多可能。很多离谱的决策可能就是少部分人一拍脑门决定的,比如有人可能会提出用学识来进行分配,或者可能用人与人之间的互动度来分配,或者可能依旧是按工作来分配,毕竟从 AI 的角度来说,人类这个生物还是有一些比机器优秀的地方的,特别是从发展的眼光来看,机器替代人是需要一个过程。特别是,替代那些有权力的人。

    虽然如此,但我还是会去思考如何度过这个过程。做那些自己觉得有意义的事情。

2024

  1. 以华为的技术储备,做一款替代AR1的芯片和对应的产品,应该可以非常具有颠覆性的竞争力。25年相关的新技术也都可以量产了

  2. Publishing Your Deno Project as a Monorepo using dnt

    Publishing Your Deno Project as a Monorepo using dnt

    Before providing theoretical guidance, let's look at how to achieve this in practice. After completion, I will explain the advantages of this project management solution.

    Tools

    1. deno
    2. pnpm

    Preparation

    1. Create your project:
      deno init dnt-mono
      # cd dnt-mono
      # code . # open in ide
    2. Initialize a git repository
  3. 使用 dnt 将你的 deno 项目发布成 monorepo 风格

    使用 dnt 将你的 deno 项目发布成 monorepo 风格

    在提供理论指导之前,我们先看具体的实践如何做到,完成后,我再说明这种项目管理方案的优势在哪里。

    工具

    1. deno
    2. pnpm

    准备工作

    1. 创建你的项目:
      deno init dnt-mono
      # cd dnt-mono
      # code . # open in ide
    2. 初始化 git 仓库
  4. MutableSharedFlow 随记

    MutableSharedFlow 作为一个建立在 Flow 基础上的设计,它的 Shared 特性其实与 Flow 的 collect 有着设计上的冲突。 因为 Shared 特性,它的 emit 与它的订阅者有关系,订阅者的消费速度决定着它的发射速度。然而如果没有消费者,就意味着它的 emit 会直接丢失,而没有被消费到。 举个例子:

    val sharedFlow = MutableSharedFlow<Int>();
    launch {
        sharedFlow.collect {
            println(it) // 这里通常不会有任何打印
        }
    }
    sharedFlow.emit(1)

    因为 launch 的执行需要时间,在这段时间里,emit 可能已经执行完毕了,从而导致发射的值没有被任何人消费从而丢失。 这对于将 MutableSharedFlow 直接作为 EventEmitter 的替代者来说,会是一个很严重的设计缺陷。


2023

  1. 我发现浏览器有一个很离谱的 BUG,我不知道它是出于什么原因

    import { a } from "http:/127.0.0.1:8000/test.mjs";
    console.log(a);

    这个协议头不规范,居然能宽容地正确解析出来。 也就意味着在浏览器中,new URL("https:/qaq.dweb/index.ts") 能被合法解析成 new URL("https://qaq.dweb/index.ts"):

    这个 bug,可以带来一个玩法。我可以利用这个 bug,用 node 实现类似 deno 的功能。因为 deno 近乎是完全使用浏览器的标准,所以说浏览器上面的这个 bug,在 deno 中同样也会有,也同样适用…… 在 nodejs 项目里,只需要在 node_modules 里头创建一个 https: 的文件夹。它完全不会报错,可以正确解析。

    比如说以下 deno 代码:

    import { Server } from "https:/deno.land/std@0.187.0/http/server.ts"; // 这里使用单斜杆,也会被认为是双斜杠

    然后同样的代码,在 nodejs 项目中,不启用 deno,只添加一个 tsconfig.json,使用 ts5+ 来实现 .ts 文件后缀的支持

    // tsconfig.json
    {
      "compilerOptions": {
        "target": "ES2020",
        "module": "ESNext",
        "moduleResolution": "bundler",
        "allowImportingTsExtensions": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true
      }
    }

    最终效果如下图:

  2. 这是社区的讨论:Add onclose event to MessagePort #1766 当初我提到一个垫片方案,那时是 2020 年,所以当初只有 chrome69+的内核能支持:

    /// worker
    const lockReqId = "process-live-" + Date.now() + Math.random();
    navigator.locks.request(lockReqId, () => new Promise(() => {}));
    postMessage(lockReqId);
    
    /// master
    worker.addEventListener("message", (me) => {
      if (typeof me.data === "string" && me.data.startsWith("process-live-")) {
        navigator.locks.request(me.data, () => {
          worker.dispatchEvent(new CloseEvent("close"));
        });
      }
    });

    现在已经普遍支持

    caniuse-locks

  3. Web Design Principles 这篇文章提供了 Web 平台的接口设计最佳实践

2022

  1. 在本机配置 CNAME

    1. 安装 dnsmasq

      sudo apt-get install dnsmasq
    2. 配置 dnsmasq

      vi /etc/dnsmasq.d/test.conf # 随便开一个文件

      填入:

      cname=from.gaubee.com,to.gaubee.com
    3. 修改本地 dns 配置:

  2. 基于AsyncIterator的响应式编程

    最近在重新思考响应式编程的一些事情,其实我很少使用 RxJS,往往是直接手撸各种异步策略。 因为我自己是更加倾向于使用原生的 async-await/generaor 来实现。因为会有更好的调式支持,性能也会更好。但可维护性可能就不一定,如果没有好好封装,别人读代码的时候,就会比较晦涩。 虽然 RxJS 在开始的时候也是晦涩,但是至少他们的高级的概念能够很好的复用。 而像我这种直接手撸的就往往是按照需求来进行编程,阅读者如果对需求没有足够的理解,那这种代码的可维护性可以说是相对比较低的。

    但最近有打算把 RxJS 的一些常见概念和我自己的经验结合起来,写一个基于异步迭代器的响应式编程的库。 这篇文章就简单的讲一下这个库里头涉及到的一些有趣的经验点。

    首先就是我异步编程时最常使用的 PromiseOut,它是对 promise 的再封装

    class PromiseOut<T> {
      resolve: Function;
      reject: Function;
      promise = new Promise<T>((resolve, reject) => {
        this.resolve = resolve;
        this.reject = reject;
      });
    }

2021

  1. 尝试 Deploy to GitHub Pages

  2. Event模块是用于快速记录一些小事件。比如一些想法;一些值得分享的链接;一些图片等等

  3. Web 未来技术猜想(一)

    对于近十年来 Web 技术的高速发展,很有多精彩的概念与设计涌现出来,但也有很多设计是建立在历史 Web 技术的架构上。

    这间接地导致了浏览器的开发越来越难,现在还存活的浏览器内核也就只剩下 Webkit 和 Blink 了(Firefix 的 Servo 份额实在太小了,开发进度也实在缓慢)……

    即便这两个内核的代码都是开源的,但并不意味着“不垄断”,Web 技术再这样发展下去,只会制造出越来越高的技术壁垒。因为开源并不意味着自由,技术标准的话语权还是掌握在别人手里,你想贡献代码,还得看社区是否“有时间”去接纳,还得有大量的条条框框在限制着你,而反观 Chrome 团队,它们则是能肆无忌惮地往 Chrome 中添加各种实验性功能。从技术层面上来说,技术人的贡献固然是令人尊敬值得肯定,但从资本的层面上来说,这些新技术的堆在这般的堆砌,制造技术壁垒、掌握标准话语权,不正是垄断牟利的老套路吗?

    我这里大胆预测一下,未来 Web 技术一定带来突变。 或者说这不是预测,是我个人假设要去从头设计一个浏览器,我应该怎么去做。宏观上会分成两大种类的模块来开发:

    第一种是功能性模块

    比如蓝牙模块、HTTP1/2/3 协议模块、USB 模块、摄像头模块等等。对此可以理解成“驱动模块”,但不同的是,驱动模块目的只是将硬件被操作系统的接口所认知,功能性模块还加入了隐私保护的概念,所有的行为对于使用者来说必须是公开透明的。这不是单纯做好“功能授权”与“信息流向透明”就能解决的问题,还是确保用户的身份不被追踪,用户的偏好不被预测等等。 这类模块由两部分组成:一部分是“原子接口”,一部分是“应用接口”。

    1. 其中“原子接口”只能由操作系统提供,类似于操作系统的 API,但是要符合上文所提到的 Web 的隐私安全性的定义。

      Web 开发者可以直接在网页上进行使用 WASM/JS 围绕“原子接口”进行开发。

      比如说摄像头模块的原子接口,可以做到对相机预览功能的二次开发,或者直接拿到 YUV、RGB、RAW 等格式进行处理等等。但现实情况是,每一个物理硬件都有它的特性,我们只能说这些硬件在出厂的时候通过了可用性的测试,但并无法保证所有的硬件都是一致的,所以我们往往需要加入一个理想数据模型,来结合实际硬件的情况,加入一定的偏移与噪点来消除误差,这其实是需要硬件厂商和系统驱动要去解决的问题。

    2. 其次“应用接口”是基于“原子接口”开发出来的应用。首先操作系统会提供一套默认的“应用接口”,正因为将浏览器的开发成本嫁接到操作系统上,并将之模块化,才有可能将浏览器的开发成本大大降低。
  4. CSS“文字”渐变,一种比background-clip通用性更好的方案,可以用于SVG中(CSS svg icon gradients, a more versatile solution than background-clip)

    示例 Demo

    SOME TEXT
    背景色 Background Color