阅读视图

发现新文章,点击刷新页面。

我的 WordPress 网站安装了哪些插件(2025.06)

WordPress 插件是扩展网站功能的强大工具,用户无需编写代码即可轻松添加各种特性和功能。插件种类繁多,包括 SEO 优化、社交分享、电子商务、网站安全等,用户可以根据需求自由选择和安装,从而显著提升网站的灵活性与可操作性。除了市面上的成熟插件包,我们还可以通过添加增强扩展(如纯代码形式的插件)来进一步扩展功能与性能,例如官方曾经发布的对象存储插件 object-cache.php

这些丰富的插件和主题构成了 WordPress 强大的生态系统,正是这一生态让 WordPress 成为全球最受欢迎的建站平台,魅力无可比拟。那么,关于必备插件的推荐,实际上并没有一个固定答案。因为当前的 WordPress 核心程序已经非常完善,从安全性、样式、编辑器等方面都能满足大多数用户的需求。加之海量的主题市场,许多曾经流行的个性功能已经直接集成到系统和主题中了,比如懒加载、灯箱效果、缓存功能等。

因此,我建议你根据实际需求选择和安装插件,这不仅可以节省精力和时间、提高性能,还能避免安装恶意插件导致系统崩溃。如果非要说有哪些插件是必备的,那大概是 Akismet 你好多莉 吧。毕竟,当你完成 WordPress 的安装时,它们已经默默地存在了,哈哈。

[ 阅读全文 ]

原文链接: https://www.shephe.com/website/wordpress-plugin-recommendations/
版权声明: Kevin's Space 版权所有,转载请用明链标明本文地址
本站相关: 随机文章 | 站长微博 | 关于本站 | 联系站长 | 捐助作者

游戏组件的一生: 从加载到上屏

1. 小游戏容器与游戏引擎

小游戏容器的设计上可以理解是一种特化版的 WebView,渲染上下文上裁剪了多余的 DOM Element,只保留 Canvas;而脚本引擎上则 JS Polyfill 或是容器 Binding 的方式去对齐 ECMA-262 的标准。此外容器还需要提供 Script 加载与执行、WASM 等新标准处理、以及 Audio 与 Video 等多媒体能力,这些能力都将通过 JSBinding 的形式,将接口包装成 BOM 的形式给到 JS 侧使用。

小游戏容器之所以要设计成符合 Web 标准的容器,是为了兼容不同游戏引擎。这种设计理念的本质是将底层平台能力标准化、通用化,把碎片化的硬件、系统能力屏蔽在容器内部,只向上提供一套与浏览器 BOM、DOM 类似的编程模型,使得各类游戏引擎(如 Cocos、Egret、Laya、Unity WebGL)都可以以 Web 的运行环境的方式接入,避免每个引擎都去适配各家平台的原生能力。这实际上是 WebView 本地化、轻量化的一次再演化,小游戏容器约等于一个轻量浏览器内核。

这个过程中容器负责“平台标准化”,引擎负责“内容生态”,比如

小游戏容器的职责:

  • 提供统一的渲染上下文(Canvas/WebGL)。
  • 提供统一的脚本运行时(JS/WASM)。
  • 提供标准化的输入、音频、视频、多媒体 API。
  • 提供网络、存储、支付、分享、广告等平台能力封装。
  • 对接安全沙箱、权限管理、性能隔离等系统层。

游戏引擎的职责:

  • 提供高层抽象的场景管理、物理引擎、动画、资源管理。
  • 提供开发者友好的编辑器、调试工具链。
  • 提供跨平台的组件化开发范式(UI、骨骼动画、粒子系统等)。
  • 管理游戏生命周期、状态同步、渲染调度。

接下来,以 Cocos 引擎的渲染管线为例,介绍小游戏容器对资源的加载流程以及对游戏组件的渲染流程。

2. 游戏引擎中的三大循环

游戏引擎的渲染管线由三大循环进行驱动,分别是渲染循环、事件循环和游戏循环,以下是梳理出来的三大循环的全景图:

2.1 渲染循环 RenderLoop

首先是渲染循环,它的主流程如下图所示:

整个渲染循环由系统的 Vsync 信号驱动,iOS 由 CADisplayLink 发起,通过应用进程的主线程的 RunLoop 来执行渲染任务,具备一定的帧率控制能力,如 iOS 下可以设定 30/60/90/120 FPS。

在引擎侧,核心流程做了 3 件事:

  1. glFlush 清空 GL 缓冲指令:将上帧未执行的 OpenGL 指令强制刷新,确保显存与帧缓区数据一致,防止由于指令堆积导致的“帧延迟”或“卡顿”。
  2. UpdateScheduler 异步任务调度:调度当前帧需要触发的异步任务,例如音频回调、网络事件响应等。保证非渲染逻辑(如数据更新)与渲染解耦,提高主线程并发能力。
  3. Tick 驱动 JS 层逻辑:每帧通过 Binding 固定调用 JS 侧 Tick 方法,执行动画、状态更新等与渲染相关的逻辑。从而实现逻辑层与渲染层的解耦,增强跨平台的适配能力。

在容器侧,iOS 通过 CAEAGLayer 处理 GL 指令上屏,主要有两个步骤:

  1. glBindRenderbuffer绑定 RenderBuffer:将当前帧渲染结果绑定至 RenderBuffer,作为上屏缓冲区。
  2. PresentRenderbuffer 显示输出:将 RenderBuffer 内容呈现至屏幕,实现用户可见的最终画面。

在 iOS 渲染体系中,最终负责显示的组件是 CAEAGLLayer。它作为 Layer 树(Layer Tree) 的一部分,直接引用共享内存中的渲染缓冲区(Renderbuffer 数据)。与此同时,系统的 Compositor(合成器) 会将 CAEAGLLayer 的内容与其他 UI 元素(如 UIKit、SwiftUI)进行统一合成,最终输出到屏幕。

在每一帧的 Tick 任务 中,JavaScript 会与游戏引擎协作,生成本帧所需的 Framebuffer(详见 3.5 至 3.10 节)。此时,Core Animation 与 OpenGL ES 通过共享渲染缓冲区实现数据同步。这意味着,OpenGL 渲染结果实质上只是一块 Layer 树中的画布,最终仍需与系统 UI 层级一同被合成为最终显示图像。

当然,本文中涉及的小游戏容器仅使用了 OpenGL 作为渲染后端,随着 Metal、Vulkan 等新一代图形 API 的兴起,RenderBuffer 绑定与上屏流程将更倾向“并行渲染 + 异步上屏”,提升高帧率下的流畅度与低延迟体验。 这个渲染循环的逻辑是同步执行的,因此如果将帧率设置为 60 FPS 时,以上所说的一帧的逻辑没有在 16.6ms 内运行完,便会导致 Jank。

比如在这个 Bad case 中,运行 Tick 任务时,在主线程的 JS 执行了 136ms,就导致了游戏动画卡顿:

因此,为了保证游戏运行的流程性,意味着我们需要不停地打磨性能,尽可能降低同步任务的耗时。性能优化一定要借助 Profiling 工具,以下是一些常用的工具:

  1. Xcode GPU Frame Debugger:针对 iOS 平台的图形调试工具,能够深入分析 渲染管线级别的性能瓶颈,尤其适合 Metal 与 OpenGL ES 开发场景。
  2. RenderDoc:业界主流的跨平台图形调试工具,支持捕捉帧数据,分析渲染管线各阶段的资源与性能瓶颈,适用于 OpenGL、Vulkan、DirectX 等 API。
  3. inspector.js:Web 端可以使用,便于在 WebGL 场景下分析 DrawCall、着色器与资源绑定等性能数据。
  4. Mali offline shader compiler:https://zhuanlan.zhihu.com/p/161761815,适用于 ARM Mali GPU 的离线着色器编译与分析工具,可用于评估 Shader 复杂度与指令执行成本,优化移动端渲染性能。
  5. Snapdragon Profiler: 抓帧工具,支持统计 Heavy DrawCallOverdraw,帮助识别渲染瓶颈与冗余计算。

2.2 事件循环 EventLoop

我们向下,从 Tick 任务进入到第二个循环 —— 事件循环。

因为小游戏容器不是 WebView,只有一个 JS 引擎,因此我们需要实现一个事件循环机制,驱动 JS 执行(不一定完全对齐浏览器标准,只需要满足容器要求即可)。由图可见,主要包括 3 个任务:

  1. 消费 timer 等宏任务:处理通过 setTimeout、setInterval 等方式注册的定时任务,确保定时逻辑的正确触发。
  2. 消费 rAF 任务:这一步主要是为了驱动 GameLoop 逻辑,游戏主循环通常挂载于 rAF 回调中,用于逐帧更新渲染与逻辑。
  3. 清空当前帧的 Commands:执行渲染命令、界面更新等待处理的指令,完成本帧渲染周期。

这里重点说一下 rAF 的实现。在早期,rAF 通过 setTimeout(0) 来模拟实现,链路如下:

可以发现这里是存在问题的:

  1. 不合规范:是使用 setTimeout 0 模拟的,并非 vsync 直接驱动。
  2. 链路太长:Native 来维护 Timer 队列,等待 vsync 信号消费完之后再回调给 JS。

后来按照 WHATWG 标准进行了重构,

优点如下:

  1. 标准化:vsync 后直接触发 JS 的调用
  2. 开销小:JS 维护 Timers 队列,移除原生层中转的 JSBinding 调用开销。

可见渲染性能的优化,关乎在很多实现的细节上,需要挖掘与打磨。

最终,通过以上的事件循环,容器能够维持 JS 引擎与渲染系统之间的协同工作,实现游戏的持续运行与更新。

2.3 游戏循环 GameLoop

这一部分展开来说就是第 3 章——游戏组件的一生:

在展开画卷之前,介绍一下传统的使用 OpenGL 作为渲染后端的小游戏容器的渲染流程:

首先是资源加载,涉及到两种完全不同的资源处理——脚本资源和静态资源。脚本资源由 JS Runtime 进行处理,而静态资源则针对不同类型的文件又有各自的处理方案——包括图片、字体、音频、视频、还有比较特殊的骨骼动画。因为本文主要说渲染,就不展开介绍资源加载流程了。

之后,这些资源被游戏引擎渲染关键处理,由 JS 驱动生成 WebGL 指令,通过 JS Binding 最终调用到 C++ 或 Native 侧的 OpenGL 指令集上 —— WebGL 是 OpenGL 的子集,因此可以一一对应。

这个过程往往会出现很多渲染瓶颈,因此其中会涉及到很多优化项。我们根据硬件资源来看,主要关注 CPU、GPU 和带宽。而在当下移动端硬件资源并不富裕的场景下,对于游戏的优化,本质上变成了“平衡的艺术” —— 我们需要去平衡 CPU、GPU 和带宽资源。即如果瓶颈不能消灭,就需要转移瓶颈,比如经常见的是从 CPU 移到 GPU —— 使用 Computer Shader、GPU skinning、Animation Bake、GPU particles 等等。

对于 CPU,这是最常见的瓶颈。这里不展开说游戏业务侧的优化项(减少 DrawCall 的 Culling、Batching 这些),而是从容器侧提供一些优化思路。

  • 比如上面的 JS Binding 调用可能会导致瓶颈,那我们可能会去做合批,从两方面去实现,一方面是调用次数合批,做 CommandBuffer 增加吞吐;另一方面可以做调用实现的合并,比如提供 GFX 高级图形库。
  • 还比如一些 JS 同步任务会阻塞主线程,那么就把计算密集型的任务转到 Native 去做。
  • 比如 JS 自身解释执行的执行效率,那就想办法用 JIT 或者 WASM。
  • 再比如 GC 上,也有一些优化的地方。

对于 GPU,如果产生瓶颈了,一般是由于 Fragment Shader 指令太复杂,或者 Vertex Buffer 过大,比如 3D 渲染中的三角形面数超过阈值,一般移动端场景下需要控制在 50 万面到 150 万面之间。另外,高 Overdraw 也会导致 GPU 多做很多无用功。

对于带宽瓶颈,则主要是靠压缩纹理(桌面端还可以用延迟渲染和后处理技术)。在网上有这么一个结论:

如果你的游戏跑 60 帧,那么每帧可用的带宽将会是 21024/60 = 34M, 假设你的 GBuffer 的分辨率是 1280 \ 1080,那么写一次 GBuffer(RGBA 4 个字节)的带宽大小为: 12801080\4/1024/1024 = 5.2M, 如果 3 张则是 15.6M.

考虑到一般你的游戏都会有 Overdraw, 假设 Overdraw 比较合理在 1.5 左右,那么这样的带宽消耗就能占到 15.6 * 1.5 = 23.4 M。 考虑到你还要渲染场景,ui 和角色等内容,这样很容易就超过了每秒 34M 的推荐带宽占用。

下图是一个常见的同步渲染管线:

  1. 应用层提供顶点数据
  2. 构建顶点着色器对顶点进行标准化
  3. 图元装配构建几何图元
  4. 光栅化阶段,将图元离散化为片元,每个片元对应屏幕上的像素区域
  5. 片元着色器对每个片元执行纹理采样、颜色计算、雾效等像素级处理。
  6. 进行测试与混合操作(Alpha、深度、模板测试),并将结果写入帧缓冲区 Framebuffer。

构建完 Framebuffer 后,就回到了我们 2.1 节所说的 CAEAGLLayer 绘制上屏了。

接下来,我们就展开画卷,看看游戏组件的一生。

3. 游戏组件的一生

对于游戏组件从加载到上屏的流程我画了一张图:

把这个流程可以简单拆成 10 个阶段:

为了介绍清楚这个流程,我准备了一个最简单的 Cocos 游戏 Demo。这个是 Demo 的场景设计:

这个是主场景的代码:

const { ccclass } = cc._decorator;
@ccclass
export default class Helloworld extends cc.Component {
protected onLoad(): void {
console.log('onLoad');
}
start () {
console.log('Hello World');
}
}

3.1 Load Assets

首先是资源加载,前文介绍过游戏资源可以分为静态资源和脚本资源。由于静态资源的加载流程涉及的内容太多了,本节只简单介绍下脚本资源加载。

包括 3 类脚本资源:

  1. 内置脚本:引擎启动的时候进行加载,包括注册 JS Binding、实现 window 对象(基础的 BOM 和 Canvas DOM 对象)、polyfill 补齐 ES 标准等等。这个脚本内置在容器里,容器启动 JS 引擎的时候直接加载。这一步可以做多实例和预执行,以加快启动速度。
  2. 入口脚本:容器需要一个入口脚本,类似与 Web 里的 HTML,以便引入游戏入口资源。
  3. 动态加载的脚本:由游戏入口资源引入,比如游戏框架代码、游戏包里的 JS 资源等等。

这里可以容器侧可以提供离线资源、preload、prefetch、预执行等方式进行优化,同时在 JS 引擎方面也可以扩展做下 Code Cache,避免重复的编译耗时。

3.2 Component Scheduler

脚本资源加载执行后,游戏组件代码会进入到组件调度器中进行优先级调度。

Cocos 组件的生命周期如下图左所示,在 3 个关键的生命周期环境分别存在对应的调度器,每个调度器里设计了三个优先级队列,本质上每个队列的内容是由链表进行组织,顺序执行注册好的 invoker。

具体而言,从业务侧视角来看:在场景编辑器中创建节点(Node)时,业务方可以为其命名,并通过勾选“active”属性来决定该节点是否默认激活。一旦节点被标记为激活,加载阶段将由 Node Activator 负责激活该节点,接着 Component Activator(组件调度器的一部分)会依次激活该节点所挂载的各个组件,同时触发组件所在场景(Scene)的激活流程。最终,激活后的场景会将节点挂载入层级树,并完成组件 Invoker 的注册,交由调度器统一调度与管理。

整体流程如下图所示:

我们的 Demo 游戏组件的 start 生命周期下打印了一个 “Hello World”,调度堆栈如下所示:

3.3 Render Scene

当场景激活并挂载了对应组件之后,接下来便是渲染场景,这一步就涉及到从 JS 调用到了 Native —— 即需要将 Scene 数据传递给 Native 侧,从而触发 Native 的 Render 流程。

JS 和 Native 互相调用的方式有很多,适用场景也不同,这里也不展开说了。需要注意的是,在架构设计上,这里可以对 Binding 层做一层抽象,以便容器对接不同的 JS 引擎实现。

另外需要注意的是 Binding 要做好两端的 GC,因此 Binding 的实现上需要符合 RAII 原则:

3.4 Batcher

当 Native 拿到节点之后,便需要进行 Batch,这一步属于计算密集型,因此选择放在 Native 侧去做。

Batch 的流程比较复杂,核心思想是通过 DFS 对场景中的 Node 进行遍历,计算并装配(Assembler)顶点数据,得到顶点缓冲(VertexBuffer)和索引缓冲(IndexBuffer):

我们 Demo 游戏的场景树结构相对简单,遍历从 root 开始向下遍历(别忘了 Camera):

装配的计算流程比较复杂,下面仅对装配的结果做一个拆解,方便读者理解数据的由来。对于小恐龙而言,它是一个 Sprite2D,装备时会转成 Texture2D 处理,而后者在这个环节的核心,是需要拿到网格数据(Mesh Buffer)。下图是最后计算得到的 Mesh Buffer。

Mesh Buffer 由 Vertex Buffer 构成,这里装配的 Mesh Buffer,共 80 字节,其中每个顶点 20 字节,那么可以容易拆出 4 个 Vertex Buffer,同时根据 a_uv 的定义和偏移能拿到各自的 uv 坐标:

例如,根据顶点着色器的代码我们知道这个 Vertex Buffer 包括 3 部分数据:

  • a_position: 偏移量 0,8 字节。vec2,能算出来一个坐标。
  • a_uv0: 偏移量 8,8 字节。vec2,就是 x,y,算出来之后是(0,1)。
  • a_color: 偏移量 16,4 字节。vec4,RGBA,数值是 0xFFFFFFFF,即白色透明。

我们把四个顶点的坐标都算一下,可以拿到宽高和左上角的坐标,其实可以发现,这个数据就是业务侧在场景编辑器里对 Node 的宽高和坐标设置:

顶点装配完毕之后的 Node 会被放进 Models 里,最后做成 Scece Tree 中的 models 节点:

3.5 Setup

这个环节主要由两个逻辑组成:

  1. 设置 Framebuffer 和 Viewport
  2. 将 Scene 里的各个 Model 转成 drawItems 队列

首先是第一个部分,设置 Framebuffer 和 Viewport。具体而言,包括以下步骤:

  1. 通过 setFrameBuffer 函数调用 glBindFramebuffer 绑定 Framebuffer 帧缓冲对象,并分别附加颜色缓冲(COLOR_ATTACHMENT,存储渲染的颜色信息)、深度缓冲(DEPTH_ATTACHMENT,存储每个像素的深度信息,用于深度测试)和模板缓冲(STENCIL_ATTACHMENT,存储模板测试的结果),确保后续绘制有正确的渲染目标。
  2. setViewport 调用 glViewport 设置视口,决定最终渲染区域在屏幕上的映射范围
  3. setup clear 依次执行 glClearColorglClearDepthglClearStencil,初始化颜色、深度和模板缓冲的清除值,为每一帧绘制提供干净的初始状态。
unsigned int fbo;
glGenFramebuffers(1, &fbo);

接下来,游戏引擎会将 Scene 里的各个 Model 转成一对一的 DrawItem,一个 DrawItem 的数据结构如下所示:

最后,引擎将这些 DrawItem 组装成 DrawItems 队列,以便后续流程处理。

3.6 Render Stage

接下来进入 Render Stage 阶段,渲染管线会开始对 DrawItems 进行分类处理。根据渲染的 Material 的需求,DrawItems 会被分发至三个不同的 Pass,分别对应 Opaque、Shadowcast 和 Transparent 三个阶段,关系到材质属性和阴影投射:

  • Opaque:用于绘制完全遮挡光线的物体,如墙面、地板、角色模型等。这类物体会首先渲染,通过深度缓冲区(Z-Buffer)完成遮挡剔除,避免后续无效绘制,提升渲染效率。
  • Shadowcast:专门处理场景中的阴影投射。此阶段会根据光源信息,对具有投影能力的物体进行阴影绘制,为场景添加真实感与空间深度,尤其适用于强光源或需要表现光影效果的环境。
  • Transparent:负责绘制允许光线穿透的半透明物体,如玻璃、水面、特效粒子等。透明物体通常需要根据视角进行深度排序,以保证前后层次正确渲染,避免视觉穿插错误。

通过将 DrawItems 按照物体特性分发至不同 Pass,渲染管线能够有针对性地对 Effect 进行实现。

业务侧可以在代码里创建一个指定的 Material,之后管线就会走到对应的 pass 进行处理:

// 创建一个立方体网格
const cube = new cc.MeshRenderer();
cube.mesh = cc.GizmoMesh.createBox(1, 1, 1);
// 设置材质为不透明
const opaqueMaterial = cc.Material.create();
opaqueMaterial.initialize({
effectName: 'builtin-unlit',
technique: 'opaque',
});
cube.setMaterial(opaqueMaterial, 0);

因为我们 Demo 较为简单,因此最后生成的 StageInfo 只包含 Opaque Pass:

当然,在 Cocos 中也是支持自定义渲染管线,实际上就是自定义这个环节的 Passes,定义完之后可以直接应用在 Opaque、Shadowcast 和 Transparent 三个阶段之上:

3.7 ModelView Transformation

经过 Passes 之后,场景中的 DrawItems 会根据其属性被分别送入 OpaqueStage Renderer、Shadowcast Renderer 和 Transparent Renderer 进行初步处理。各个 Renderer 在此阶段主要负责更新与视图相关的 Uniforms(如矩阵、材质参数等),以确保后续渲染过程中所需的视角、空间信息正确。这一部分可归类为 View Transformation 阶段,统一完成视图坐标系下的变换数据准备。

紧接着不同的渲染阶段会有差异化的预处理操作:不透明物体和透明物体会分别执行 SubmitLight 以提交光照信息,而投影阶段则专门进行 SubmitShadow 以生成阴影数据。同时,透明阶段由于涉及深度排序问题,还会额外执行 Calculate zdist 以计算对象的深度信息。

所有这些预处理完成之后,最终将统一进入 ModelView Transformation 阶段,得到视图投影矩阵,从而完成从模型空间到屏幕空间的最终变换,以便于后续的图元栅格化与像素着色工作。

在讲解 ModelView Transformation 之前,先来介绍下游戏系统中的坐标系统的定义。一般会涉及物体坐标、世界坐标与相机坐标三种主要坐标系。

  1. 物体坐标系:以物体自身的中心点(anchor 通常设置为(0.5, 0.5))为原点,用于描述物体内部各个部位的位置关系,便于定义复杂物体内部的原子结构关系。
  2. 世界坐标系:则是以整个场景的中心作为原点,用来统一描述场景内所有物体、相机以及光源的位置关系,确保场景整体的空间一致性。
  3. 相机坐标系:以相机的位置作为原点,是为了将 3D 空间转化为 2D 图像,以便进行计算和渲染。

基于这套坐标系统下,观测变换(Viewing Transformation)主要包括视图变换、模型变换与投影变换三个步骤。

  1. 视图变换:可看作是将相机放置到场景中的过程,主要是定义相机的朝向和位置。
  2. 模型变换:对物体进行放置或调整位置、旋转以及缩放等操作。
  3. 投影变换:类似于摄影,通过投影方式,将三维物体的信息映射到二维的屏幕空间。

下面重点说说投影变换(Projection Transformation),它分为正交投影(Orthographic Projection)与透视投影(Perspective Projection)两种方式。

  • 正交投影常用于工程制图软件,不体现远近透视效果;
  • 透视投影广泛应用于游戏、渲染引擎中,能更真实地模拟人眼观察到的空间透视效果。

而透视投影的数学本质是压缩加上正交投影的结合,实际将一个无限延伸的观察空间(视锥体)转化为一个便于计算的立方体。

这里简单画了个图来介绍透视变换的实现,fov(视角)定义相机的视场宽度,可以分为水平fov与垂直 fov;distance 定义投影平面与相机之间的距离。视景空间通过近裁剪平面(near)和远裁剪平面(far)定义渲染的范围,通过相似三角形的计算,最终将 3D 空间映射到 2D 屏幕(Canvas)。

说完了透视投影,我们再看看投影变换的另一种方式——正交投影。其通常有实现的方式有两种:

  1. 直接舍弃Z坐标,将 3D 物体转化为 2D 物体,直观但无法表现空间深度;
  2. 将观察空间变换成标准的立方体后,利用变换矩阵进行计算。

综上,坐标转换流程具体包括物体坐标到世界坐标,再到相机坐标,接着到投影坐标,最终映射到屏幕坐标。

  1. 首先,在编辑器中定义坐标相加的关系,将物体放置到场景中;
  2. 之后,通过视图变换调整相机位置、模型变换调整物体位置;
  3. 再经过投影变换将 3D 空间投射到 2D 空间;
  4. 最后进行坐标系转换,确保渲染到正确的屏幕位置。

在这个过程中,会计算得到视图矩阵(View Matrix)、投影矩阵(Projection Matrix),最终矩阵相乘拿到视图投影矩阵(Model-View-Projection Matrix)。我们结合 Demo 游戏的断点数据,分别看看他们仨是怎么计算得到的。

首先是视图矩阵,它负责将世界坐标系转化为相机坐标系,其中包含坐标轴的缩放和平移操作。实际计算中,通常涉及坐标轴补齐,即齐次坐标的补齐过程,确保矩阵运算的有效性。

之后是计算投影矩阵,它用于将相机空间进一步映射到标准化的设备空间(Normalized Device Coordinates, NDC),矩阵中的缩放系数根据屏幕的宽高比和设定的正交高度来计算。

最终的渲染过程通常使用视图投影矩阵(Model-View-Projection Matrix, MVP)。视图投影矩阵是视图矩阵与投影矩阵的组合,用于最终的顶点变换和着色器渲染计算。

3.8 Link Program

接下来进入到着色器的创建与 Link 阶段,首先是创建图元:

之后是创建顶点着色器和片元着色器:

值得关注的是,在 Cocos 中有一共有 11 个内置着色器,其中前 5 个处理 2D 渲染相关,builtin-clear-stencil|vs|fs 用于清楚模板缓冲区,7-10 3D 渲染相关,最后一个用于处理 3D 光照:

  1. builtin-2d-spine|vs|fs
  2. builtin-2d-graphics|vs|fs
  3. builtin-2d-label|vs|fs
  4. builtin-2d-sprite|vs|fs
  5. builtin-2d-gray-sprite|vs|fs
  6. builtin-clear-stencil|vs|fs
  7. builtin-3d-trail|particle-trail:vs_main|tinted-fs:add
  8. builtin-3d-trail|particle-trail:vs_main|tinted-fs:multiply
  9. builtin-3d-trail|particle-trail:vs_main|no-tint-fs:addSmooth
  10. builtin-3d-trail|particle-trail:vs_main|no-tint-fs:premultiplied
  11. builtin-unlit|unlit-vs|unlit-fs

文中的 Demo 是使用内置着色器模板进行创建的。

接着创建着色器程序,Link 上我们创建的顶点着色器和片元着色器。紧接着,设置着色器中所需要的 Uniforms 变量,这里就包括纹理和我们上一步计算得到的视图投影矩阵:

最终,我们的 Framebuffer 会附着上颜色附件、深度附件与模板附件:

需要注意的是对于刚创建完的 FrameBuffer 不能立即使用,因为它还不完整(Complete)。而一个完整的帧缓冲需要满足以下的条件:

  • 附加至少一个缓冲(颜色、深度或模板缓冲)。
  • 至少有一个 GL_COLOR_ATTACHMENT。
  • 所有的附件都必须是完整的(保留了内存)。
  • 若开启 Multisampling,则每个缓冲都应该有相同的样本数(sample)。

因此需要使用 glCheckFramebufferStatus 对缓冲区的完整性做出检查:

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
// ...
// notify native: getInstance()->glErrorCallback(GL_ERROR, errMsg);
return;
}

3.9 Blend & Test

接着依次进入执行 混合(Blend)、深度测试(Depth Test)、模版测试(Stencil Test)。

首先是 Blend,顾名思义讲两个颜色进行混合。下图展示了混合方程的计算方式:

OpenGL 中常用的混合函数如下图所示:

下面是一个简单的例子,使用着色器来创建红色蒙版的 Blend 效果:

深度测试(Depth Test)在图形渲染中用来决定每个像素是否显示。启用深度测试时,OpenGL会将当前片段的深度值与深度缓冲区的值进行比较。如果通过测试,深度缓冲区将更新为新的深度值,否则该片段会被丢弃。下图展示了 OpenGL 中常用的深度测试函数:

而模板测试(Stencil Test)则用于限制渲染区域。通过模板缓冲区,可以在渲染时创建特殊的区域标记,只有符合模板缓冲区设定条件的片段才会被渲染到屏幕上。模板缓冲区允许实现诸如阴影、镜面效果、轮廓高亮等复杂渲染效果。下图展示了 OpenGL 中常用的模版测试函数:

上述的结果最终都会与 Framebuffer 的 Attachment 机制相关联。Framebuffer 的 Attachment 机制决定了渲染结果如何输出到缓冲区中。Framebuffer 通常会附带多个 buffer,包括颜色缓冲区(GL_COLOR_ATTACHMENT)、深度缓冲区(GL_DEPTH_ATTACHMENT)和模板缓冲区(GL_STENCIL_ATTACHMENT),他们共同决定了最终渲染的结果。

3.10 Commit & Draw Pass

到了管线的最后一步,便是提交(Commit)和绘制(Draw)。

在 Cocos 中每一帧会存储两种状态,一个是当前画面帧的状态(currentState),另一个是我们即将渲染帧的状态(nextState)。

我们需要依次计算 nextState 中的各个部分的 state,之后将 nextState 和 currentState 的状态值做 diff,如果某个环节的状态值不一致,便会触发 commit 操作。以便管线最大程度利用缓存结果。

下面依次介绍下管线中需要管理的状态值:

  1. Blend States、Depth States、Stencil States
  2. Cull Mode
  3. Vertex Buffer
  4. Program
  5. Textures
  6. Uniforms

其中 Program 通常在管线初始化时所有的着色器都会准备好,非极端情况下缓存不会失效,因此上面的图中没有标出这个状态。

Blend States、Depth States、Stencil States 分别存储了我们前文所说的 Blend、Depth Test、Stencil Test 过程中涉及到的 GL 调用的参数和部分结果,这里就不详述了。

接着是 Cull Mode,根据顶点的索引的顺逆时针来用来区分正面与反面,如果状态值和 currentState 不一样,便触发 glCullFace 的调用来进行 commit。

对应顶点缓冲区也是一样有状态值管理,如果变脏了,就需要重新调用 glBindBuffer 进行绑定:

着色器程序也是一样的,如果脏了,就重新调用 glUseProgram 进行设置:

接着便是对 Textures 的检查和提交,这里有两个知识点:

  1. 纹理的应用:具体涉及到 glActiveTextureglBindTexture。首先使用 glActiveTexture 函数来选择当前要激活的纹理单元,这一步决定了接下来绑定的纹理将作用于哪个纹理单元上。然后,通过 glBindTexture 函数将具体的纹理对象绑定到特定的纹理目标上。通过这种机制,纹理对象与对应的纹理单元和目标进行关联,从而完成纹理的激活与绑定操作。
  2. 纹理单元:用于表示显卡可以同时管理的多个纹理。默认情况下,GL_TEXTURE0 纹理单元总是被激活的状态。此外,OpenGL 规范保证至少支持 16 个纹理单元(即从GL_TEXTURE0GL_TEXTURE15)。纹理单元是按顺序定义的,因此我们可以通过诸如 GL_TEXTURE0 + 8 的方式便捷地访问特定编号的纹理单元,以便在复杂的渲染场景中实现多纹理同时使用。

当前面的状态值都准备并提交完毕后,最后需要管理的状态值是 Uniforms,这一步如果有脏区产生,也需要重新提交 Uniforms 变量。比如游戏 Demo,涉及到的 Uniforms 变量有 cc_matViewProjtexture

最后就是绘制了,其中在每一帧的绘制前都需要调用 glClear 清理 Freambuffer 的状态。下图展示了 gl 指令调用的时序:

由于游戏 Demo 比较简单,绘制只需要准备好纹理和 Uniforms 即可,最后调用 glDrawArraysglDrawElements 将准备好 Framebuffer 绘制上屏:

至此,经历了这一系列的管线处理之后,我们的 Demo 游戏在小游戏容器内完成了上屏。

扩展阅读

  • 《GAMES 101》
  • 《计算机图形学入门:3D渲染指南》
  • LearnOpenGLCN

对网吧的偏见

对网吧的偏见 - 第1张图片

我对网吧的偏见,源于小学时候。

学校对面有一家网吧,从知道那是网吧开始,到它停止营业,从未进去过,因为时不时就有老师或主任在放学后去网吧逮学生,第二天在广播里通报,再加上家人和老师不断地告知网吧里全是不三不四的社会人,很危险,随时都会被敲诈,现在回想起来,并不无道理。

怕被老师逮到,也怕被坏人欺负,再加上我平时几乎没有机会接触电脑,直到今天,去网吧的次数屈指可数。小学对面的网吧,当时的价格是2元/小时,包宿应该更便宜,但对于每天零花钱只有1元的我来说,也是承担不起的价格;第一次去网吧,得益于同学请客,已经记不清当时坐在电脑面前玩什么游戏,只记得那时候的心情十分忐忑,即便是周六,也担心突然被老师逮到,去网吧上网似乎成了一种罪过;还有一次在同学的带领下,去过一趟所谓的黑网吧,不查身份证,不管你多大,给钱就开机,房间很小,头一次觉得这里确实是一些不三不四的社会人……后来随着学习压力增加,学习时间紧张,读初一的时候家里买了电脑,便再也没有去过网吧,高中毕业之后约过同学去包宿,难受和煎熬,想玩又犯困,以及现在,双休前的最后一个工作日,如果兴致来了,去楼下的网吧玩两个小时,就已经很满足了。

前段时间还在犹豫,想买游戏本打游戏,考虑到自己不仅打得菜,而且平时很少有时间玩,还不如想玩的时候去网吧玩一会来的划算,于是买了 Mac mini M4。附近有不少网吧,以前叫网吧,现在叫网咖的居多,不仅配置和环境更好,价格也更贵了。第一次来南昌,陪女朋友考试,考试期间我就去附近的一家网鱼网咖玩游戏,10元/小时的价格让我惊讶,这还是大厅的价,如果是包厢岂不是更贵?今年寒假,和几个同学开了一间电竞酒店房,有四台电脑,这边四个同学玩游戏,那边四个同学在打牌,累了困了就在床上睡一会,又一次刷新了我对网吧、网咖、电竞酒店的认识和体验。

不怕别人笑话,因为去网吧去得少,我都不清楚上机的过程,如何让老板给我开一台机子,怎么登陆,没带身份证怎么办……也是在高中毕业之后和同学一起去网吧次数多了,渐渐熟悉一点,没带身份证不碍事,打开微信使用 V 上网公众号实名激活就行,接着再让老板充值网费,随便找电脑开机等等。

申公豹说得对,人心中的成见是一座大山,从小对网吧的偏见在我心中也是一座大山,给它打上了不太好的标签,但也影响不了什么,从现在来看,网吧是让我在工作之余放松自我的地方,话又说回来,有条件的话还是尽量在自家房间里玩游戏,环境更好,今天去附近的网吧玩了两个小时,虽然开着空调,但是空气中弥漫着一股奇怪的味道,人多、嘈杂,或许以后还是会选择配置一台 Windows 电脑,每个男人心中都有一个电竞房的梦想。

对网吧的偏见》最先出现在印记

20250515

今天的惊喜来自和菜头老师在公众号槽边往事写的文章提到了谜底黑胶,《聊点我喜欢的:Wiim 和谜底黑胶》

之前谜底黑胶也有在别的文章或者视频出镜过,不同的是和菜头老师去“调查”了我,他看到了我的日常,我的黑胶设备,他理解了为什么我会而且我能做出这样一个产品。有一种被懂了的感觉。

今天研究了 Claude + Apple Music MCP 的一些玩法,希望它能给我推荐音乐创建歌单。不过我找的这个 MCP 不太合适,有空要尝试一下另一个。

下午高兴完了就去打麻将了,蛰伏两圈,每圈仅小胡一把。第三圈直接连庄外加四个财神加持,一把翻身。前面两圈让我放平心态,今天就是来陪玩的,于是只专心搞大的,当财神看我可怜分配给我四个白板的时候,我抓住了机会。人生就要抓住机会啊。

自業自得

读作じごうじとく(jigō jitoku),日语里「自作自受」的意思。即自己的业障、自己所得。

自作自受的「标准」在哪里?如果一个当事人遭遇了某些在外人看上是自作自受的剧情,但是他却觉得这是一种难得的人生体验,难道我们要把这个人绑起来打到他屈服,让他承认他就应该「自作自受」?很显然,期待自作自受结局的仍然是「观众」。

我膝盖上有个疤痕,是小时候摔跤之后结痂没两天我就抠破的代价。当时上药的医生用阻吓的方式警告我,抠破结痂就会留下一辈子的疤痕,但是我又手贱,所以总是时不时地扣上两下,直到有一天我躺在床上抠破了结痂,血喷出来的那一刻我具象化了「自作自受」。

因为第二天我的衣服上、床上、墙上都是血迹,免不了一顿臭骂。但是我自己倒是合理化了这个自作自受的结果——结痂扣掉之后,伤口不痒啦!从此之后,所谓的「自作自受」就跟「油漆未干」一样,我不摸一下我怎么知道油漆干没干。

所以基本上自作自受这四个字的恐吓对我来说已经完全失效了,反倒变成了「买个教训」。


从小到大需要面临的「自作自受」情况有很多,比如「现在不好好学习将来没钱吃饭没人管你」「你如果这段时间玩过去了,暑假最后两天赶作业就知道痛苦了」「你太早谈恋爱就会耽误学习,到时候想谈恋爱还没人要」「等你到了我们这个年纪你才知道赚钱有多么辛苦」……

不得不说,这些场景预判都是非常好的剧本设定,即五分钟内将主角拉入剧情的「邀请」,比如一个不听话的小男孩突然在一夜之间长大成人,10岁的灵魂带着40岁的人生去体验他期待的「我长大以后一定会怎样」,或者说是父母苦口婆心想让他理解的「自作自受」。

没错,这个「一夜之间」就是好莱坞电影的类型之一了,例如《辣妈辣妹》《重返十七岁》《夏洛特烦恼》《羞羞的铁拳》——这一类型的电影被称之为「愿望成真」。这一类电影之所以受欢迎(我说的是市场反馈,不是您的个人喜好),是因为它既满足了幻想,也会让观众从一开始就带着强烈的「自作自受」预期。

《凪》里我埋下了这一期的引子——没人喜欢完美的主角,如果他没有缺陷那就很难与观众形成共鸣。比如我前段时间在客厅看过几次片段剧情的《成家》,一群圣母嬲竟然是为了「善良」在帮助剧情里的每一个角色——哈?

那如果是完美的角色,他的每一个选择、每一个行为都会阴差阳错地带来好运,这个时候观众就会期待「陷阱」的出现,否则他的故事何必要「拍成」电影呢?这便是「愿望成真」这类电影的内核:

把主角(也是观众期待的)最迫切的愿望实现之后,会如何?

  • 主角是弱者(不完美的)
    • 因为同情,所以观众 希望 弱者的愿望被实现;
    • 但同时观众 不希望 弱者永远是「赢家」,所以也期待着「自作自受」的发生;
  • 主角是强者(完美的)
    • 令人 生厌 的同时,又让观众察觉到主角身上的「可悲」与「闪光点」;
    • 所以他必须接受「自作自受」,但他从中学会了那些让观众感到 愉悦 的特质;

不得不说,所谓的「剧本结构」,其实就是通过情绪来控制观众感官的过程(我说的是市场反馈,不是您的个人喜好)。想让人们厌恶一个角色的同时,只要稍加技巧,也可以让这种厌恶中带着一丝怜悯,以至于到最后开始同情和理解「坏人之所以变坏」的合理性。前面举例的那四部电影都是「愿望成真」中的一个子类别「身体交换」,即通过交换性别、年龄或是种族等,最终角色学会感恩。当然,这也是最容易出现「正能量自我感动」的烂片的原因。


从剧本跳脱出来,现实几乎不可能发生「愿望成真」的时候,这种场景更容易发生在「睡前妄想症」的情形当中。

从剧本的结构而言,人们对于「愿望成真」的情感又是极其哲学辩证的——我可以接受他愿望成真,但这个成真的代价就是有一段「自作自受」的剧情,让他重新理解自己得到的一切——这想必是我们在童年接受的教育,他们的底层逻辑竟然是一模一样的。

「我可以给你买这个玩具,但是你先要考到100分;如果给你买也可以,但是你如果下一次考不到100分,我会立马收走这个玩具。」——愿望、条件和诅咒。

这便是「愿望成真」的另外两个剧本内核:

  • 条件:得到「魔法」要付出的代价,代价 就是在过程中 追求自我
  • 诅咒:既然有「魔法」也有使用魔法后必然遭受的 对等诅咒

现实虽然没有「魔法」和它引发的「愿望成真」,但剧本里的内核却同样适用。「愿望成真」是一个极其双标的存在,当别人的愿望成真时,就应该按照剧本的结构去引发那些他即将面对的「自作自受」,但自己的愿望成真又不想付出那些对等的诅咒代价。

代价就是代价,它不会因为一个人的善良、邪恶、好与坏、对与错而发生本质上的改变。它存在于每一个选项的背后,但是这个代价本身是没有好坏之分的。

如果一个当事人遭遇了某些在外人看上是自作自受的剧情,但是他却觉得这是一种难得的人生体验……

这才是人生剧本里的「愿望成真」。


昨天有人在 Telegram 给我留言,问我剧本创作是否可以完全脱离现实生活凭空创造。我还没来得及回答,这是个很庞大的问题,都说「艺术源于生活、但高于生活」,但如果完全记录的是生活中那些狗屁倒灶的事,这样的作品可能就身边几个人看完能会心一笑,市场只会觉得「它跟我有什么关系」。

我也试过创造完全架空的剧本,结果很惨,因为陷入到完全主观的幻想之中,就很容易创造出「旅游导览」式的作品,这正好就是下一期想聊的话题。简单来说,所谓的「旅游导览」就是当创作者创造了一个精美巧妙的世界观后,他其实是很恐惧有人(甚至是主角)去毁掉这里的规则。最后就变成了主角在一个幻想世界束手束脚游历参观的过程——不是谁都能如此潜心地完成《荷马史诗》。

影视作品是反馈现实的「期望」,「梦想成真」就是其中一个类别,但并不是因为有了形式才有了公式,而是因为这个公式就是人性的一部分,只是作品将它们毫无遗漏地暴露,成为了最露骨且直观的表达。

科技爱好者周刊(第 348 期):李飞飞,从移民到 AI 明星

这里记录每周值得分享的科技内容,周五发布。

本杂志开源,欢迎投稿。另有《谁在招人》服务,发布程序员招聘信息。合作请邮件联系(yifeng.ruan@gmail.com)。

封面图

5月1日,宇宙飞船造型的深圳科技馆新馆开馆,上图是设计团队在新馆前合影。(via

李飞飞,从移民到 AI 明星

大家知道李飞飞吧,AI 的明星教授。

她在斯坦福大学任教,是美国国家工程院等三院院士,担任过斯坦福 AI 实验室主任,以及谷歌云 AI 首席科学家。

她1976年出生于北京,在成都长大,16岁全家移民美国。

我一直好奇,她怎么走上 AI 这条路,从移民变成学术明星?

这几天,我读完她的自传《我看见的世界》(中信出版集团,2024),才发现她的人生很有戏剧性,每当重要关头,都有幸运的事情发生

(1)高中阶段

她出生于一个普通家庭,中学阶段并无过人之处。

我们家位于成都当时的外环路旁边,小区由三栋一模一样的塔楼组成,我家住在四楼。这个环路是不断扩张的城市边缘,一侧是工厂,另一侧是农田。

我进入了一所吸引全市优秀学生的中学。在那几年里,对女孩的预设和偏见让我越来越不耐烦,这种情绪已经超出了课业的范围。在同龄人中,我已经有"假小子"的称号。

1992年,移民美国后,她家的生活顿时变得困难。一家三口挤在新泽西乡下一间一居室公寓,她睡客厅,床就放在餐桌旁边。

父亲在一家华人商店修理旧相机,后来被辞退,从此失业。母亲做杂货店营业员,后因风湿性心脏病,回家休养。李飞飞下课后,就要去打工,有时在中餐馆端盘子12个小时,每小时2美元。

最后,实在走投无路,她们家决定买下社区的一家干洗店,靠洗衣为生。买下干洗店需要10万美元,全家仅有2万美元储蓄,其余8万美元都是借的。

(2)大学阶段

1997年,李飞飞中学毕业,要申请大学了。

一开始,我的目标大学主要是州立大学和社区大学,而不是常春藤学校。但我一直对一所顶级高校念念不忘,那就是普林斯顿大学。

我们是一个靠从车库市场淘来的旧货才能勉强度日的家庭,连我用的计算器都是坏的,我们怎么可能负担得起常春藤学校的学费呢?

尽管如此,我还是无法抑制内心的冲动,提交了申请。就算只是象征性地申请一下,我也感觉具有特殊意义。

她申请了普林斯顿大学,结果好梦成真,普林斯顿给了全额奖学金。

如果没有全奖,以她家的经济状况,负担不了学费。如果不去普林斯顿大学,她就不太可能走上学术道路了,更不要说后面的成就了。

(3)博士阶段

大学毕业后,李飞飞原想去华尔街工作,解决家庭的经济问题。

母亲鼓励她,继续追求自己的梦想。于是,她选择去加州理工学院读研究生,方向是视觉识别机制。

2004年,李飞飞为了写博士论文,需要图片材料,来训练算法。她找了9000张图片,组成了一个图片集,手工对每张图片进行分类标注,一共分成101类。

这个图片集叫做 Caltech 101,算法经过训练,就能从新图片识别出这101类物品。她因此顺利拿到了博士学位。

(4)助教阶段

博士毕业后,李飞飞先去伊利诺伊大学,后去普林斯顿大学,都是担任计算机科学的助教。

她继续探索视觉识别,想找到一种通用算法,能够识别所有种类的物品,而不是 Caltech 101 那样,只能识别出101类物品。

这意味着她需要一个超大的图片训练集,能够包含了世界上所有物品。这可太难了,所有人都反对这件事。

我们都是年轻的助理教授,所处的院系竞争激烈,在事业起步的那几年里,我们都面临着"要么发表论文,要么完蛋走人"的局面。压力之下,我们必须马不停蹄、保质保量地完成工作,因为我们知道,稍有懈怠就可能与终身教授的职位说再见,一同失去的还有获得稳定生计的最佳机会。

我听到的劝阻之声已经多得够我用一辈子了(可能下辈子也够了).

有上万个类别的数据集有什么用?大部分模型连一两个类别都识别不准!

你知道用这么多图像训练一个模型要花多长时间吗?这个时间可是用"年"来计算的。

别人要怎么下载呢?你这个图像总量比大多数硬盘的存储量还要大。

具体怎么做,你有计划了吗?几百万张图谁来做标注?要花多长时间?怎么验证所有内容的准确性呢?

(5)ImageNet

李飞飞坚持要做,这个通用图片集起名为 ImageNet。那时是2006年。

她想到一个思路,英语词典有一些基本名词,用来解释其他所有物品。只要统计一下,基本名词有多少个,每一个又有多少变体,那就得到了所有物品的基本类别。

统计结果是3万类。因此,李飞飞估计,ImageNet 将有3万个类别,总共包含2000万张图片,每张图片都要有分类和标注,需要从几亿张图片里面筛选出来。

我们发出了邮件,招募愿意帮忙从网上下载和标注图片的本科生,工作时间灵活,每小时10美元。我们招募到一些学生,但是按照这样的进度,完成整个项目需要19年。

这太慢了,项目方法做了改进,用脚本自动去谷歌搜索图片,然后抓取。但是这样也需要人工核对和筛选,只把19年的时间缩短到18年。

幸运的是,亚马逊刚刚发布了众包平台"土耳其机器人"(Amazon Mechanical Turk,AMT)。在这个平台上,你可以出钱,通过互联网,把任务分包给世界各地接活的人。

他们通过这个平台,将 ImageNet 分包出去,投入的人数一下子扩展到几千人,而人均费用只是原来的几十分之一。

2009年6月,ImageNet 的初始版本终于完成了。我们成功达成了目标:收集了1500万张图片,涵盖了2.2万个不同类别。这些图片筛选自近10亿张候选图片,并由来自167个国家的4.8万多名全球贡献者进行了标注。

(6)ILSVRC 算法竞赛

ImageNet 虽然完成了,但在学术界毫无反响,没有太多人关注。

我们遇到了第一个也是最严重的挫折:在当年的"计算机视觉与模式识别大会"上,ImageNet 被降级为"海报展示"。

所谓的"海报展示"是一个学术术语,意味着我们将不能在演讲厅内向听众展示我们的工作,只能在会场的指定区域里摆放一幅印有项目摘要的大幅海报,希望能引起路人的兴趣。

我想过 ImageNet 可能被证明是对的,也可能被证明是错的,对于这两种可能性,我都做好了准备。无论是哪种结果,都会是一个学习的机会。然而,我万万没想到,它被忽视了。

由于 ImageNet 得不到承认,李飞飞想到一个办法,她要每年举行一次算法比赛,看看哪种算法识别 ImageNet 图片集的正确率最高。

这样一来,在计算机视觉领域,ImageNet 就会成为一个比较基准,各种算法都需要用它表示自己的识别能力,大家就不会忽视它了。这个比赛叫做 ILSVRC(ImageNet 大型视觉识别挑战赛,ImageNet Large Scale Visual Recognition Challenge)。

2010年,第一届比赛令人失望,11个团队提交了35个参赛算法。冠军算法是传统的图片向量比较,并无创新之处,正确率也不高。

2011年,第二届比赛更惨,获胜算法还是图片向量比较,正确率只提高了2个百分点。这意味着,没有任何创新和进展。

最糟糕的是,参赛人数也出现急剧下降,参赛算法从35个减少到15个,愿意为此付出努力的人似乎越来越少。

说这种经历"让人羞愧"已经远远不足以描述我们的心情了。为了推动 ImageNet 的发展,我们倾注了多年的心血,搜集的图片数量远远超过以往的任何数据集,还精心策划了一场国际竞赛来探索它的能力,但结果却只是简单地重复了现状。如果说ImageNet 是一场赌注,是时候开始思考我们是不是已经输了。

眼看这个项目就要失败了,几年的心血付之东流。就在这个时候,李飞飞人生最大的惊喜和反转来临了。

2012年,第三届比赛,一个加拿大团队使用被学术界遗忘已久的卷积神经网络,一举将图片识别正确率提高了10%。

接下来的事情,就是被写进教科书的历史了。全世界被神经网络的效果轰动了,AI 研究出现突破,人类进入 AI 时代。

李飞飞彻底翻身,一举成名,从助教变成世界知名的 AI 研究领头人物,人生从此海阔天空。

她的故事令人感叹,如果神经网络算法没有在2012年出现,而是再晚几年,或者更早一点,亚马逊的土耳其机器人众包平台没有在2005年诞生,一切会怎样?

这就是时运吧。科学家的人生和科学发现一样,都是由一些偶然事件推动的。个人奋斗固然重要,但是关键时刻还是离不开幸运。

科技动态

(1)传统的脑电图,需要在头上布满电极(下图),有很多限制,也不舒适。

美国宾州大学的科学家,发明了一种头发电极,细得像头发一样,可以直接粘在皮肤上,淋浴和运动也不会掉下。

这种电极目前还是有线的,但是有计划开发无线版本。

(2)百度地图在导航路面植入广告。

(3)谷歌的 AI 笔记应用 NotebookLM,可能很快就会添加"视频概览"功能。

它已经支持生成音频和 AI 问答,如果再支持生成视频,简直难以想象,是否还需要真人老师。

直接上传课本,它就生成讲课视频了。

(4)安卓官方的桌面模式,泄露了运行照片。下图是它的多窗口模式。

但是 Android 16 可能来不及,发布要等到 Android 17。

手机当作桌面电脑,已经不远了。

(5)百度公布"动物语言转换方法、装置、电子设备及存储介质"专利,使用 AI 识别动物的情感状态,转换为人类能够理解的语言,从而实现动物与人类之间的情感交流和理解。

文章

1、一段让 Chromium 机器人崩溃的代码(英文)

作者介绍了一段 JS 代码,让Chromium 无头浏览器(Puppeteer 和 Playwright)崩溃。它可以用来识别,访问者是不是机器人。

2、Git worktree 简介(英文)

Git 仓库同时只能有一个工作区,如果想同时建立多个工作区,可以使用 git worktree 命令。

3、用 Go 移植 TypeScript 的重要影响(中文)

微软官方要用 Go 语言重写 TypeScript 项目,本文分析这样做的目的和影响。(@imbant 投稿)

4、为什么大模型可以控制手机(中文)

开源项目 droidrun 可以通过大模型,以自然语言操作安卓手机的 APP。本文分析它是如何做到的。(@lezhi12 投稿)

5、创业公司可能无法承受微服务(英文)

本文提出,微服务需要很强的运维能力,并会增加代码复杂性,创业公司不要盲目采用,单体应用更简单。

6、从 Prettier 和 ESLint 迁移到 BiomeJS(英文)

BiomeJS 是用 Rust 语言写的工具,对 JS 代码进行格式化和语法检查,速度极快,可以取代 Prettier 和 ESLint。

7、如何自己托管 Obsidian(英文)

Obsidian 是一个优秀的笔记软件,作者给出详细步骤,自己托管 Obsidian 服务器,从而在任何地方都可以通过浏览器使用。

工具

1、Void

开源的 AI 代码编辑器,Cursor 的替代品,基于 VS Code。

2、Hyvector

在线的矢量图(SVG 文件)编辑工具。

3、Karakeep

一个自搭建的书签 App,提供全文搜索和 AI 自动分类标签,参见介绍文章

4、PairDrop

局域网传输文件的 Web 应用,代码开源,类似于 ShareDropLocalSend

5、zVault

NAS 操作系统 TrueNAS 原本基于 FreeBSD,正在转向 Linux。zVault 是一个社区的分支,由社区推动继续在 FreeBSD 开发。

6、YAMLResume

使用 YAML 格式创建简历,并通过 LaTeX 输出 PDF,方便进行版本管理。(@xiaohanyu 投稿)

7、AllinSSL

开源的 SSL 证书自动化管理平台,集证书申请、管理、部署和监控于一体。(@KincaidYang 投稿)

8、Basecoat

一套基于 Shadcn UI 的组件库,但是不使用 React。

9、Scraperr

网络爬虫的 Web 控制台。

AI 相关

1、MathModelAgent

开源的 AI 应用,自动完成数学建模,生成一份完整的论文。(@jihe520 投稿)

2、BiliFilter

基于本地大模型的 Bilibili 弹幕过滤器,对弹幕分类过滤。(@ddddng 投稿)

3、AI 语音克隆

免费的语音克隆工具,3 秒录音克隆人声。(@xiaodaidai0701 投稿)

资源

1、I Don't Have Spotify

一个音乐搜索引擎,输入 Spotify、YouTube、Apple、SoundCloud 的音乐链接,它会提供该音乐在其他网站的链接。

2、IPinfo Lite

地理位置数据库 IPinfo 推出的免费服务,IP 查询地理位置,无需信用卡,API 请求次数不受限制。

1、Web Component 教程

英文的 Web Component 入门教程。

图片

1、数字键盘的样式

数字键盘来源于电话。

早期的电话都采用旋转的拨号盘。20世纪50年代,电话可以长途直拨了,拨打长途电话需要输入11个号码,拨号盘就太麻烦了,导致了数字键盘的诞生。

1955年,AT&T 公司的研究人员,做过一个研究,10个数字的小键盘应该怎样排列,效率最高?

他们一共列出了15种排列。

经过研究和比较,用户更喜欢从左到右、从上到下的布局。

具体来说,两排五列水平布局与现在普遍使用的 3x3+1 布局速度相当,差异很小。

AT&T 公司最终为电话选择了 3x3+1 布局,主要原因大概是它比较紧凑。

文摘

1、我第一次加入创业公司的教训

一位开发者大学毕业后,加入了一家创业公司。

他逐渐发现,公司内部有很多矛盾,产品决策也有失误。

最终,公司开始走下坡路,他就提交了辞呈,放弃了自己的期权。

离职后,他写了一篇文章,总结了自己得到的教训。

(1)即使创业公司的每个员工都很有动力,但如果创始人并非顶尖人才,那么取得巨大成功的机会很低(但你仍然可以从中学到很多东西)。

(2)创业公司只有两种工作:开发和销售。如果创始人既不做开发,也不做销售,不知道他在做什么,那就相信你的直觉吧。

(3)创业公司的产品还未得到市场验证的情况下,为多个平台构建原生应用,是一种极其低效的行为。如果同时为两个产品在每个平台开发两个原生应用,简直是疯了。

(4)创业公司的路演,大多是浪费时间。产品的验证来自于与用户交流和迭代,而不是打动评委。

(5)没有什么比并肩作战、共同实现梦想更神奇的了。如果你经常见不到创始人,所有的沟通都只能通过远程进行,那可不是好兆头。

(6)如果创业公司没有经过严格的面试,就录用了你,这是一个危险信号。他们到底是基于能力来录用你,还是因为你是第一个同意只收很少的报酬,就为他们工作的工程师?

言论

1、

科学项目日益大型化和制度化,使得个人的好奇心和创新,对于科学的推动正在减弱。科学的进步越来越依靠有效的组织和大量的投入。

-- 《思想家和实干家》

2、

除非你参与过历史遗留项目,否则你不能自称高级工程师。

-- infobip.com

3、

是什么让硅谷的公司如此强大?

不仅仅是它们数十亿美元的资金或数十亿用户,也不仅仅是因为它们拥有惊人计算能力和数据储备,让学术实验室的资源相形见绌。它们之所以强大,是因为成千上万个才华横溢的人在同一个屋檐下共同努力。

-- 《李飞飞自传》

4、

以前的小团队是1名高级开发人员 + 5名初级开发人员,以后是1名高级开发人员 + AI 大模型。

-- Hacker News 读者

5、

我打赌,以后的工程师必须深入底层,更接近硅片的层面。开发应用程序将不再需要精通技术的人,AI 让每个人都可以开发自己的应用程序。

-- Hacker News 读者

往年回顾

OpenAI 的图书馆工位(#301)

国产单板机值得推荐(#251)

中国需要成立半导体部(#201)

NFT 是什么,听说能赚钱(#151)

(完)

文档信息

  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证
  • 发表日期: 2025年5月16日

众生牛马

周五,事儿还有很多没忙完,当然本质上也忙不完。这段时间早七点晚九点的忙,一天十四个小时的干活,也算是鞠躬尽瘁了,当然死而后已还谈不上,我还想多活几十年。

这一个月左右的时间,密集的进行各项工作的优化和调整,从二级班子的全员竞聘到全院质量与安全体系的重构,从临床专科的建设到整体人力资源与绩效考核的再造,一切都在忙而不乱的节奏中稳步前行。

IMG_20250427_074441.jpg

当然,整个推进过程中,总有一些磕磕碰碰,不过框架搭好了,方向明确了,接下来就该是撸起袖子加油干了。很多时候,我们需要做到“无碍”,言行自由,心灵轻盈自在。不报有固定的鄙闻漏见,不坚持死板的条条框框,以一颗平和清静之心去待人接物,像水一样随物成形,而不像石头一样冥顽不灵。

当然,我们也需要慈悲之心,心境通透,用广大的慈悲,把天地都纳入自己的禅院,快乐从容的平波万里。回到现实,踏踏实实的从众生牛马做起,日日是好日。

简易教程: C++的智能指针


C++ 智能指针教程

C++ 中的智能指针提供了自动且安全的内存管理。它们通过 RAII(资源获取即初始化)机制,帮助开发者避免内存泄漏和悬空指针的问题,确保对象在生命周期结束时被正确释放。

本教程将介绍 C++ 中三种主要的智能指针:

  • std::unique_ptr:独占式所有权
  • std::shared_ptr:共享式所有权
  • std::weak_ptr:非拥有式弱引用

1. std::unique_ptr

unique_ptr 拥有独占所有权。一个资源只能被一个 unique_ptr 拥有。

示例:管理简单对象

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> p = std::make_unique<int>(42);
    std::cout << "值: " << *p << "\n";

    // 转移所有权
    std::unique_ptr<int> q = std::move(p);
    if (!p) std::cout << "p 现在是空指针\n";
    std::cout << "q 指向: " << *q << "\n";
}

示例:构建链表

struct Node {
    int val;
    std::unique_ptr<Node> next;
    Node(int v) : val(v), next(nullptr) {}
};

void printList(const std::unique_ptr<Node>& head) {
    const Node* curr = head.get();
    while (curr) {
        std::cout << curr->val << " ";
        curr = curr->next.get();
    }
    std::cout << "\n";
}

int main() {
    auto head = std::make_unique<Node>(1);
    head->next = std::make_unique<Node>(2);
    head->next->next = std::make_unique<Node>(3);

    printList(head);
}

2. std::shared_ptr

shared_ptr 允许多个指针共享同一个资源的所有权。它通过引用计数管理资源,当引用数为零时自动释放内存。

示例:共享资源

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> a = std::make_shared<int>(100);
    std::shared_ptr<int> b = a;

    std::cout << "a 的引用计数: " << a.use_count() << "\n";
    std::cout << "b 的引用计数: " << b.use_count() << "\n";
    std::cout << "*b = " << *b << "\n";
}

示例:共享链表节点

struct Node {
    int val;
    std::shared_ptr<Node> next;
    Node(int v) : val(v), next(nullptr) {}
};

3. std::weak_ptr

weak_ptr 是一种弱引用,不拥有资源,仅用于观察 shared_ptr 所管理的对象。它常用于打破循环引用,防止内存泄漏。

示例:打破循环引用

#include <iostream>
#include <memory>

struct B;

struct A {
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A 被销毁\n"; }
};

struct B {
    std::weak_ptr<A> a_ptr;
    ~B() { std::cout << "B 被销毁\n"; }
};

int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    a->b_ptr = b;
    b->a_ptr = a;
}

是否存在 make_weak?

不存在 std::make_weak,因为 weak_ptr 不拥有资源,它必须引用一个已存在的 shared_ptr

如何创建 weak_ptr

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> sp = std::make_shared<int>(42);
    std::weak_ptr<int> wp = sp;

    if (auto locked = wp.lock()) {
        std::cout << "值: " << *locked << "\n";
    } else {
        std::cout << "对象已被释放\n";
    }
}

总结

智能指针 所有权 线程安全的引用计数 典型用途
unique_ptr 独占 N/A 高效、安全的单一所有权
shared_ptr 共享 多个所有者共享资源
weak_ptr N/A 打破 shared_ptr 的循环引用

C/C++编程

英文:Tutorial on C++ Smart Pointers

本文一共 375 个汉字, 你数一下对不对.
简易教程: C++的智能指针. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 简易教程: C++的智能指针 C++ C++ 学习笔记 程序设计 编程 计算机
The post 简易教程: C++的智能指针 first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 被动收入之: 微博红包 今年开始重新经营我的微博帐号 drlai 收到两笔微信红包,应该是来自于官方的支持,150元(成功提现到支付宝)。虽然这不能持久,也没多少,但毕竟实现了零的突破,意义重大。 如果流量上来,内容创作者可能会接受到比较多的赞赏,这也是一个比较简单的变现方法。这也能作为一种被动收入,不过如果不是头部网红,可能杯水车薪,但如果你有好几个类似这样的,也能积少成多! 在用户中心,微博用户可以每天登陆手机微博APP打卡,获取点数和少量的红包钱(几分钱),积少成多! 微博做些小任务可获得积分和几分钱。聊胜于无。 微博的主要盈利模式 微博的主要盈利模式主要包括以下几个方面: 广告收入:微博的大部分收入来源于广告,尤其是品牌广告和效果广告。广告形式包括信息流广告(类似于推文广告)、热门话题广告、开屏广告和视频广告。品牌和企业可以利用微博庞大的用户群和社交互动来提升曝光率、推广品牌和产品。 会员服务:微博提供的VIP会员服务,用户可以支付订阅费用来享受更多的特权,比如个性化的主题、特有的表情包、私密权限设置等。这些会员服务主要面向个人用户,提升其社交体验。 直播和打赏:微博提供直播平台,用户可以通过购买虚拟礼物来支持主播,微博会从这些打赏中抽取一定比例的分成。此外,微博与内容创作者分成,通过内容付费、知识付费等形式变现。 增值服务:针对企业和大V(拥有大量粉丝的用户),微博还提供增值服务,如账号认证、粉丝数据分析、精准推送、推广和营销工具等。这些服务帮助企业提升营销效果,同时也增加了微博的收入来源。 电商和导流:微博上有大量的电商导流业务,尤其是和明星、网红的合作推广。微博用户在浏览社交内容时,可以直接跳转到商品购买链接,微博通过这种方式赚取导流佣金。 游戏联运:微博也会与一些游戏公司合作推出联合运营的游戏,微博负责推广和流量引入,用户充值或付费时,微博可以获得一部分的分成。 这些模式相结合,使得微博能够在广告市场、内容创作和电商等多个领域获利。...
  2. Javascript 中 sleep 函数实现 Javascript 中并没有 built-in 的 sleep 函数支持, 在 async/await/Promise 的支持之前, 我们可以用 busy-waiting 的方式来模拟: 1 2 3...
  3. 换了个奥迪Q5大灯花了我1000英镑 我那辆奥迪Q5 SUV今年年检没通过,原因是左前车灯坏了,需要更换。车厂告诉我,光是订购零件就要700多英镑,加上人工费,总费用得1000英镑。但没办法,如果不修,车辆年检(MOT)就过不了,车也不能上路。 MOT是英国的机动车强制性安全检测(Ministry of Transport Test)的简称。 近侧前位置灯不工作 drl/位置灯集成(4.2.1(a)(ii)) Nearside Front Position lamp not working drl/position...
  4. C++ 编程练习题: 如何合并两个二叉树? 题意: 合并两个二叉树, 没有说不可以改变原来的二叉树. 合并的时候把结点求合. C/C++ 中二叉树的定义 在C或者C++中, 二叉树的定义可以很方便的用结构体来表征. 其中左右子树都是递归定义. 1 2 3 4 5 6...
  5. 步步高学生电脑上 Basic 编程语言 peek 用法示例 步步高学生电脑 是8位FC机的经典之作.它上面的BASIC有三个版本 1.0, 2.0 和 2.1 2.1 版本有个在线帮助,实际上是 help.cmd 1.0 是用 Esc 键退回到 DOS 的,...
  6. 你给SteemIt中文微信群拖后腿了么? 这年头不缺算法, 就缺数据. 这两天花了很多时间在整API上, 整完之后自己用了一下还觉得真是挺方便的. 今天就突然想看一看自己是否给大家拖后腿了, 于是调用每日中文区微信群排行榜单的API, 刷刷拿着 NodeJs 练手: 1 2 3 4 5 6...
  7. C++ 编程练习题 – 找出第三大的数 题意: 给出一个数组, 求第三大的数字是多少, 重复的数字并不算在内, 比如 第3大的数字是1 而不是 2. Using std::set set 是集合, 是有序的(从小到大), 集合中不包含重复的元素, 所以我们可以遍历数组并把数字添加到集合中....
  8. 最简单有效的过滤WordPress垃圾评论的方法 当你的Wordpress博客流量大的时候, 不免会收到很多垃圾评论. 本文介绍一种特别简单而且免费的过滤Wordpress垃圾评论的方法. 这种方法不需要你安装任何插件, 也不需要拥有修改Wordpress主题模板函数的能力, 只需要1分钟就可以搞定. 把这个列表拷贝下来 打开 WordPress 的控制面版, 到设置-讨论 拷贝上面的列表到 “评论审核” 或者 “评论黑名单”...

借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding)


程序员的未来?Vibe Coding + AI 一起上!

借助 AI 快速开源了三个小工具

最近,我利用 ChatGPT-4o 和 o4-mini 快速开发并开源了三个小工具。起因其实很简单——每次想转换 YAML/JSON 或进行 Base64 编码时,我总是得去 Google 搜索在线工具。时间一久,我不禁开始思考:既然每次都要用,为什么不自己动手实现一个呢?正好我也在学习 React,把这个过程当作练习岂不是一举两得?

于是我开始“扮演”产品经理,向 ChatGPT 提出需求,它很快就为我搭建好了基础框架。包括项目结构、CI 工具(单元测试、ESLint——后来我换成了 Prettier)、README 文档,甚至是 GitHub Actions 上的自动化测试和部署流程,全部一气呵成。

这几个工具都部署在 GitHub Pages 上,开源、带测试、写了文档,虽然小巧,但功能完整,不需要自建服务器就能稳定运行,部署成本几乎为零。

YAML/JSON 转换工具

用于在 YAML 和 JSON 格式之间进行双向转换,支持美化和压缩,简单直观。

yaml-json-converter 借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) ChatGPT (OpenAI) 人工智能 (AI) 小技巧 程序员 程序设计 编程 资讯 软件工程

Yaml/Json数据格式转换React小程序

Github开源库 | Github Pages在线工具

Base64 编码/解码工具

支持文字和文件的编码解码操作,可以将文件内容直接转换为 Base64 字符串,或者反向解析恢复文件。

base64-converter 借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) ChatGPT (OpenAI) 人工智能 (AI) 小技巧 程序员 程序设计 编程 资讯 软件工程

Base64编码解码React小工具

Github开源库 | Github Pages在线工具

ROT47 混淆工具

这是一个轻量级的字符串混淆工具。ROT47 的特点是“加密两次即为原文”,类似于异或操作,适用于简单场景下的信息模糊处理。

rot47-converter 借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) ChatGPT (OpenAI) 人工智能 (AI) 小技巧 程序员 程序设计 编程 资讯 软件工程

ROT47 Cipher文本混淆React小工具

Github开源库 | Github Pages在线工具

程序员的门槛正在降低

AI 的发展速度太快了,现在生成代码的质量不仅更高,出错率也更低。即便出错,只需将报错信息交还给 AI,它就能分析并修正。程序员的角色正在转变:与其说是手工写代码,不如说是理解需求、与 AI 高效沟通,并拼装整合它给出的解决方案。

对我来说,项目最初的搭建一直是拖延的主要原因。ChatGPT 正好擅长这一环节——自动生成 boilerplate,让我几乎能“秒启动”一个新项目,显著提升了开发效率。

我已经养成每天使用 AI 的习惯,甚至已经很少再使用 Google 搜索。遇到问题,第一反应是直接问 ChatGPT,不仅快,还能一步到位解决问题。

Vibe Coding:AI 驱动的编程方式

Vibe Coding 这个概念今年特别火,核心思想是“用氛围编码”。也就是说,程序员不再执着于每一行代码的细节,而是通过自然语言描述需求,让 AI 来实现代码的生成、重构与调试。

Andrej Karpathy (2025)

TLDR;Vibe 编码是一种新兴的软件构建实践,它用简单的语言描述你想要的内容 – 然后让 AI 处理代码和测试。
TLDR; Vibe coding is the emerging practice of building software by describing what you want in plain language – and letting AI handle the code and test.

我发现自己越来越倾向于这种方式。遇到 bug,第一时间就将错误日志扔给 ChatGPT 处理。虽然效率很高,但也让我逐渐失去了深入思考和调试的乐趣。

现在还有很多支持 Vibe Coding 的工具,比如 Cursor,或者在 VSCode 中配置 AI Agent。你只需告诉它“我要实现什么”,它就能完成代码编写、框架搭建,甚至进行模块拆解和逻辑优化。而你要做的,仅仅是审查和接受它的建议——这不就是产品经理的工作吗?

初级程序员的挑战与机会

AI 工具的普及正在重塑编程的边界,传统“照着教程敲代码”的模式已经远远落后。未来,初级程序员面临的挑战不再是“学不会写代码”,而是“不会用 AI”。

想要不被淘汰,最重要的是掌握如何高效地与 AI 协作,提升自己的系统思考与设计能力。AI 是强大的助手,但人类的洞察、判断和创造,依然无可替代。

未来属于那些善于利用工具、不断精进自己思考能力的人。也许“写代码”的定义正在改变,但“解决问题”的本质永远不会变。

AI大大提高了生产力,执行力和创造力会更加重要。软件工程师需要懂得怎么用AI来干活拧螺丝(开发/调试/解决问题)。感觉程序员的门槛瞬间变得好低,只要懂得看懂AI生成的代码,懂得基本的软件工程就可以了。

ChatGPT 可以拿来做什么?

ChatGPT 通用人工智能

Grok 3

字节/豆包/AI

英文:From Idea to GitHub Pages: Building Tools with AI and Vibe Coding

本文一共 1266 个汉字, 你数一下对不对.
借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding). (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) ChatGPT (OpenAI) 人工智能 (AI) 小技巧 程序员 程序设计 编程 资讯 软件工程
The post 借助AI快速开源了三个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 特朗普加关税的公式竟然是EXCEL里弄的? 这两天中美关税大战越演越烈,据说,特朗普加关税的计算方式竟然是直接在EXCEL电子表格里弄的,具体如下: 其中 I 是 Import,进口;E 是 Export 出口。 优美又实用的公式家族又添新成员 勾股定理: 欧拉恒等式: 牛顿运动定律: 爱因斯坦质能等价公式: 特朗普的“互惠关税”公式:,其中 I...
  2. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  3. 测测你的幸运 – Linux Fortune-Teller LINUX 下有很好很好玩的命令,之前已经介绍过: figlet, rig, curl. 现在推荐另一个 命令 fortune 是用来随机显示一段(句)话的.fortune 在英文里就是幸运的意思. 这个命令可以不需要 参数 如果没有 可以通过 apt-get...
  4. 教娃编程有趣的瞬间 vlog视频集合 教娃700天:写在教娃编程700天, what’s next?。有很多有意思的瞬间记录一下,持续更新。 和孩子一起打闹,学习,成长。 教娃编程孩子有趣的瞬间 vlog(Day 641) 娃说我不够 Senior(Day 701) Bro.. I thought you’re like...
  5. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  6. 用 SB2000 的 FBASIC 计算圆周率后80位 英文同步 SB2000 的 FBASIC 是浮点 BASIC 的意思, 就是说可以用在计算一些数值,高级计算机.今天我们还测一下它的计算性能,之前大概知道很慢.. 计算圆周率有很多公式,收敛度不一样, 我们挑一个性价比较高的,比较容易实现的..比如这个: 在SB2000上,80位要算5 小时; 40位1个小时; 20位几分钟, 真得很慢....
  7. 推荐一款 CHROME 插件 – Wappalyzer 这个CHROME浏览器插件很方便的可以让你知道当前标签页里的网页 有用到哪些 技术. 你可以用它来检查是否插件正常工作. 1. CLOUD FLARE CDN 2. ADSENSE 3. GOOGLE ANALYTICS 4. Gravatar...
  8. 你要找什么样的老婆? 找媳妇的标准 昨天和网友在剑桥面基, 网友奔现, 他从爱尔兰过来, 小我12岁, 就聊到了找对象的标准. TLDR; 找老婆不要(只)看颜值, 而要注重性格, 为人处事和顾家等更重要的品质, 当然性和谐也很重要. 在当今社会, 人们对于找伴侣的标准有所不同. 有些人认为颜值是最重要的, 因为外貌吸引力可以让人在日常生活中感到愉悦, 这是人的本性,...

董某莹与肖某引发舆情事件迎来初步通报

4月引发的网络舆情,5月1日,国家卫健委新闻发言人表示:

近日,我委关注到中日友好医院胸外科肖某被举报所引发的相关舆情。我委已成立调查组,坚持实事求是、客观公正原则,联合有关方面对事件涉及的肖某、董某及有关机构等进行认真调查核查,对发现的违法违规问题将依法依纪严肃处理。

然后一直在昨天都没任何消息,我曾经以为这个事情就这么过去,一切交给时间。是真的没想到在今天晚上,新闻各种推送,来自国家卫健委的通报:

1、对肖某是进行了一些所谓的处罚,吊销医师执业证书,并给予五年以上禁止从事医疗卫生服务的处罚。

2、对于董某莹,仅仅是按程序撤销董某莹的毕业证书、学位证书。北京市卫生健康委依据医师管理法律法规,对董某莹医师资格证书、医师执业证书予以撤销。这是罚酒三杯的节奏啊。

3、其他情况,国家卫生健康委调查组正联合有关部门,对本次事件涉及的相关单位、人员开展深入调查,对违规违纪违法等问题将严肃追责问责。

对于董某莹的处罚,放在很多工薪阶层的普通人来说,被吊销四证意味着人生前途尽毁,已经没有其他可能性,完全不知道该如何重新站起来。而对于如董某莹这类高门贵女来说,被吊销医疗行业的四证,只不过医疗行业让她玩腻了,可以在医疗之外的9999个行业,继续大展身手,丝毫不影响她在其他行业发挥。

董小姐-董某莹

当然,今天的通报,仅仅是初步处置进展。对董董某莹、以及董某莹从入学到毕业过程中,违法为她保驾护航的这些人,后续还有哪些处理,我们拭目以待!

只是,我觉得这个事情应该就是到此为止,应该不会有下文了,已经不相信能发出什么让老百姓信任的信息,有也就是罚酒三杯的那种。在一个信任崩塌的地方,亲手毁灭的信任是很难再建立回来的。

杂记-20250515

周二把家里的电信宽带换成广电宽带,888元/年套餐送一年有线电视,不是电信千兆光纤用不起,是广电宽带更有性价比 […]

VXNA 和 Folo

除了口口相传,个人博客的曝光途径很少 。十年之约BlogFinder 算是比较经典的平台,但能见度往往也仅限于「博客爱好者」,很难出圈。

最近看博客后台数据时,VXNAFolo 给了我一些小惊喜。

Folo

Folo 弱化了 RSS 概念,转而主推大众易于理解的 「Follow、关注」,让很多新用户了解并尝试。它还简化了成为 RSS 长期用户最难的部分:寻找高质量的内容。其实,读者一旦关注足够多的「有趣博客」,会很容易养成 RSS 阅读习惯。

同一篇文章的浏览数,Folo 甚至偶尔会跟我博客后台的数据齐平。

CleanShot 2025-05-14 at 16.51.40@2x

VXNA

VXNA 则是 V2EX 的一个新功能——博客聚合器。用户可以申请收录,收录后会被定期展示。

CleanShot 2025-05-14 at 16.50.22@2x

VXNA 仅展示文章标题,点击后跳转原网站(这点对博客作者来说很贴心),所以从博客后台能很直观的看到访问数据。

目前,它已经是除了搜索引擎外,我博客最大的流量来源。

CleanShot 2025-05-14 at 16.54.00@2x

前段时间,跟朋友聊天,话题转到「写作与表达」。他觉得我「被看见的需求比较淡」,很少写追着热点的内容,大多跟着自己的兴趣走。

但我想说,「被看见,被阅读」对我很重要,只是我从没想过自己写的东西会被很多人阅读。

感谢这些为个人博客增加能见度的平台!

24/7 时间记录两年后的经验总结

Featured image of post 24/7 时间记录两年后的经验总结

《2024 年终总结:时间统计和人物属性轴》 中有提到时间追踪也画了总结图,回想一下我做这件事居然也有两年多了。只要方法和工具合适,这也可以是一件很容易坚持的事情(本三天打渔两天晒网的人如是说)。我的风格是24 小时不间断记录,杜绝时间黑洞。以前也试过只记录白天清醒的时间,但这样一是记录不够完整,二是容易有意忽略“有害活动”用空白时间作弊,导致数据不准确。24/7 全天候记录没有这些缺点,在记一段时间后就能得到一个相当准确的基准线。

没有外患,全是内忧

题外话:感谢AI帮我翻译url。


上篇文章「中年空虚」说到,我最近精神状况不太稳定。这跟情绪不稳定还不一样,因为我两者都经历过,所以可以分别。以前在育儿中遭遇过不少困难,情绪起伏大,也曾发博客记录,收获了很多安慰和建议,感恩!后来慢慢释怀了,一是认知进步了,二是“罪魁祸首”坡坡长大了,所以直接治了本。但现在的emo又升级了,变成了乌云笼罩式的无力。

找不到原因,不知道到底是真的没有原因,还是只是我没找到。想来想去只剩一个答案——年纪大了!前两天跟朋友聊天,她说到自己四十了,我小小惊讶了一下,算了算发现我也快三十七了。真的这么明显吗,确实这几年奇奇怪怪的病不少,现在右胯还在疼着,明天要去复诊。按理说我几年前开始运动,身体应该更好才对,难道不运动身体差得更快?话说连豆哥都开始运动了,哈哈,这年龄带来的紧迫感。

工作一如往常,九点上班,三点下班。下班后一小时是我珍贵的me-time,状态好的时候运动写博客,不好的时候刷剧休息。四点接小坡,然后去公园玩会儿再回家煮饭洗澡陪读睡觉。我原本想不通,明明工作时长短了许多,为什么比没生娃前还累。我自诩各方面能力都不错,可是现在的情形似乎还比不上一般的全职妈妈。就因为这,我又emo了好几天。然后因为上次emo还没结束多久就又emo,使得我更emo了。不过后来我想通了,陪娃何尝不是一份工作,甚至比职场更不可控。毕竟工作是事情,娃是人。事情听你的,娃有自己的想法呀,得引导。想到这儿,我心里一松,笼罩了几天的乌云缓缓散开。

回家后我跟豆哥说到此事,原来我一直以为自己轻松是认知不清,其实我一直在加班加点劳作啊!认识到这点后,我开始有意识地把心从娃身上收回,担心她不如多想想自己,儿孙自有儿孙福!

非常感谢博友们的评论和现身说法,emo毫无规律可言,也不讲道理。来了忍一忍,没找到原因那也就无所谓需要克服或改变什么,等这阵子过了,可能就好了。如果不好就不好吧,一有空就做点不用脑子的事,我已经不再为刷土味短剧而自责了,毕竟能让成年人快乐的事太少了。写到这我想起前阵子的感悟——我从这个世界的参与者,逐渐变成了旁观者。经历多了,也就没多少能刺激到神经的事了,这事儿着实好坏参半。好的地方在于遇事能够做到处变不惊,人稳重了许多。坏的地方在于生活变得无聊,人也没什么活力。哈哈,天知道我小时候多希望自己能变得稳重,不以物喜不以己悲。可是现在,我又开始羡慕孩童们的天真和活力。

以前大人们总说当小孩好啊,无忧无虑。长大后我觉得还是大人好,自己的事情自己说得算。可是为什么脑子里的烦恼多了许多。我一直觉得坡坡缺根筋,小孩的脑子大概因为还没发育好,所以天然呆,这才是他们无忧无虑的真相吧。我也想无忧无虑,我也想像豆哥说的那样别想那么多,可是事情总是自动出现在我的脑袋里,然后我就开始担心这忧心那。我悟了,所以过来人们极力推荐正念冥想,就为了清空大脑,跟冥想盆是一个道理。

「凡事过犹不及」实乃真理啊!啥都不想缺根筋,啥都想伤心神。所以「看山是山,看山不是山,看山是山」的三阶段便是最好的例子吗?我还在「不是山」的阶段苦苦挣扎,什么时候可以真正放下呢?是能够自己选择放下的吗?难道目标是能够从容操控思想?

控制思想
→控制对世界的看法
→控制世界的呈现
→控制世界!
唯心主义好香啊~

年纪大了,身体不中用了,向外探索的机会就少了许多。但内心世界却越来越丰富,厚积薄发,无法掌控。看来跟健身一样,我还需要健心。想我小时候,总觉得身体里有花不完的力气,每天放学还要绕操场跑三圈。而现在,则每天上演内心戏,都是年度巨作的规模。

先从看坡坡的小儿哲学书开始吧。

大大大大大美新疆

在获得了一段久违的自由后,我们就开始了一段说走就走的旅程。

书接上文,在上一篇“这道题答的,还行?”中和大家分享了一下最近的工作变动,而在工作变动之后,一个最直接的问题就是“有这么一大串的空闲时间应该拿来干什么”,变动之后情感上的失落是必然的,所以刚开始那段时间我在行为还是会有一些惯性,比如每天早上 7 点生物钟就把我叫醒了,白天那一长段的时间变得空闲以至于情绪上出现一些不适应的感觉(这个时候你说要立马去学习看书反而会觉得有点假),不过好在蒋老师和朋友们都宽慰了我不少。

前司的同事们也会时不时宽慰我几句“你是有道德的,也是一个好人,但尴尬的是遇到了一个辜负了你的公司浇灭了你的一腔热血,现在既然已经拿到钱了,就别再惦记这边的破事了,千万不要想不开。”

但事已至此,活人也不能被那啥憋死,于是我迫不及待的想找到一个短平快的方法转移我的注意力,并且尝试换个方向抬头继续往前看。当我在冥滩送快递把心态转变的差不多之后,又听到两个朋友也失业了的消息(理由也是出乎意料的一致,公司的投资方认为经营管理不及预期,为了快速上市想出了缩减员工规模的法子),于是我们在短暂而又激烈的讨论之后,就做出了这个决定,四人一队出发去新疆

之所以选择新疆的理由也很简单,在我们已知的旅游目的地中,好像只有新疆是你需要有一个大串时间安排才能够前往的旅游目的地,而且新疆历来都有“小欧洲”的称号,这里不仅没有语言与食物上的不适应,又能够让你领略到不同风格的美景。于是我们暂时安排了 10 天的计划,打算从成都前往新疆好好的耍一趟!

既然大家在短期内没有其他的安排与计划,那这里的 10 天其实也就设置的比较松散(结果玩了 12 天),不用再像以往一样担心年假和假期是不是好协调,不用担心如果节假日期间的机票涨幅有多凶,只需要让自己慢下来,静下来,做一个纯粹的游客就好了。

我们这几天的安排大概是这样的:

驾驶过程中的路线大概是这样的:

从导航的线路看得出来,这一路行程里几乎大半的时间都是在自驾,但由于新疆的地理风貌非常独特,各种风景都能尽收眼底,再加上大部分新疆高速和国道的驾乘体验都非常好(车少路宽),即使是拿到驾照不久的新手,也都有在路上试试的机会。此外值得一提的是新疆的海拔对大多数游客非常友好,最高的海拔只有在沿 G218 国道驾驶时需要翻越一座海拔 3000 米的高山,此外所有的海拔大都在 2000 米左右,不存在诸如前往西藏自驾游时需要适应海拔急剧变化的过程。

既然选择了自驾游,旅途中的燃油和相关服务费也是我们需要考虑的问题。我们从租车软件上选择了一辆 2024 款的比亚迪宋 Pro,后备箱刚好可以装入 4 个 20 升的行李箱和几个旅行书包,百公里平均 5 个油也显得这辆车的燃油性价比极高,考虑到 SUV 的底盘高度的通过性,我们这一路的驾乘体验还是比较合适的(当然租赁越野车可能更适合的是北疆的沙漠路线)。在这一整趟旅途中,除了轮胎被钉子扎破补胎的 20 块以外,我们的整备费用主要花在了洗车上,连续 10 天的驾驶和坐乘,完全不洗车即影响驾驶又影响乘坐。新疆之旅中的高速过路费+汽油费用加在一起,可能就 1000 出头,相比路上时不时出现的坦克 300,我估计至少省了一半的费用。

那下面就是这一路上的风景汇总了,所有照片都是手机直出,拍的不好还请理解~

在火车旅途中,我们一行 4 人前往餐车就餐,这种传统 K 字头火车中的餐车一般都是承包出去的,味道属于能果腹,但不好吃的,价格偏贵的样子,但好像从我记事以来餐车就一直是这样。

到达新疆之后,我们就前往了和田二街,一方面这里有许多地道饭馆,另一方面这里距离大巴扎也只有大约 10 分钟的路程。有一说一这里的饭馆和食品类型那叫一个琳琅满目,啥都有。但西北的菜品特点就是量大实在,还好我们有 4 个人,不然真的是没吃多少就吃撑了。

薄皮包子,拌面,炒面,烤肉,都是美滋滋。

赛里木湖一圈大概有约 100 公里,但东南西北四个方向的风景都不一样,能看到雪山,云杉,冰棱,乱石,风景非常出片。

我们还抽空去了一趟霍尔果斯口岸,去了一趟这里的经济合作特区但好像意义不大,没玩的没吃的,而且这里的免税购物城听说有很多假货。

在库尔德宁吃的椒麻鸡,味道超级好,还有在当地民宿发现的兰州百合。作为一个兰州人觉得挺神奇,这是我第一次看到兰州百合的幼苗(如果兰州百合不生长在兰州,那还叫兰州百合吗)。

夕阳无限好,只是近黄昏。

我记得那一天的风很大,雾也很大。

本来是想找 windowsXP 同款壁纸的,但是一路感觉比壁纸更美的风景一大把,于是也就忘了这一茬。

虽然是在新疆,但能看到的风景还包括了草原,风吹草低见牛羊的即视感。

在民宿附近吃的丸子汤和排骨,这个排骨是真的带劲,味道极好。

在那拉提的景色也让人心旷神怡,雪山,白云,草原,羊群。

堵车时在对向车道遇到的运输牛群的货车。

返程过程中,高德预估 G218 上的耗时大概有 4 个小时,但实际上由于这里正在修建新的那巴公路,整体的路面养护状况真的是一言难尽,一方面新的公路在头顶架空建设,导致有非常多的工程车和工程段落占用了原本的国道,此外由于我们旅行的过程中独库公路还没有开放,导致所有的车辆都在 G218 道路上行驶。

糟糕的路况加上见缝插针加塞插队的小车,糟糕的天气情况和可视距离,缺少维护与管制的交通情况,都导致这里的耗时远超过我们的预期。我们是在 4 日早上 8 点准时从那拉提/库尔德宁出发的,原定是计划在当天晚上 10 点左右到达吐鲁番的酒店,但因为这些问题,我们在下午 6 点才到达巩乃斯(巩乃斯,是蒙古语中“绿色谷地”的意思,位于伊犁河谷东端,就是下图中左侧的平原部分,我们在这里找了一家川菜馆及时休整,为后续的夜路做好准备)。

从那拉提东门到巩乃斯的这一段路途,大约 30 公里的路途我们开了居然快 10 个小时,人都快麻了。

如果继续冲向吐鲁番可能要在凌晨三四点才能到达。考虑到后续的休整以及依然有大段的驾驶路段,为了保证有充足的休息时间,大家可以及时调整状态,我们就立马修改目的地,前往和静县休息。

从巩乃斯前往和静县的路途中,会经过海拔3050米的艾肯达坂(也就是山口,垭口),这里的路况条件极差,一方面道路两侧的山上还有未消融的白雪覆盖,路面中则是坑坑洼洼的各种炮弹坑,我们驾驶的 SUV 虽然相对轿车有更好的通过性,但毕竟人生地不熟,看着旁边当地牌照本地人开的轿车飞来飞去,还有疯狂提速的卡车挂车,我们也只能按照安全的原则认真行驶,好歹路上蒋老师帮我盯着路况,一同的队友也给了充分的支持和信心,再加上全神贯注的驾驶,终于还是翻过了这一段艾肯达坂。

等我们到达和静县的酒店并完成入住时,已经是次日的凌晨 2 点了。不过好在由于新疆的面积确实太大了,我们认为感知新疆和内陆区域还是有一个“天气意义”上的时差,在这里等到晚上八九点时太阳才开始下山仿佛在新疆每个人每一天都会多获得 2 个小时的额外时间。所以即使是凌晨的 2 点,体感上也就是按照以往的凌晨 0 点准备休息。

和静县算是一个规模很大的县城了,也被称为新疆的心脏,如果继续从这里出发,还可以到达巴音布鲁克(就是飞驰人生里面的巴音布鲁克),去看看那里的草原,天鹅湖,开都河等等一票美丽的风景。但是连续一整天的激烈驾驶把我们一行四人也累的够呛。眼瞅着前几天的路途中大家都有些劳累了,好像再开下去也没法保持足够的旅游兴致,于是我们就打算老老实实返回乌鲁木齐。至于新疆那些我们还想去游览的城市,只有找下次的机会了。

返回新疆之后我们又去了天山天池景区,但相比前面在那拉提,库尔德宁,赛里木湖的景色,天山天池景区的风景不仅没有明显的优势,而且商业化气息过于浓重,并不能算作是外地游客有必要特地前往的景区。不过好在距离乌鲁木齐往返的时间距离都不是很远,所以这趟行程就也还好。

回到乌鲁木齐之后我们就决定在城区内随处逛逛,印象比较深刻的主要是有以下 2 个景点:

其一是新疆博物馆之旅,在这里不仅能看到伏羲女娲交尾图,五星出东方利中国锦,彩绘天王踏鬼木俑,还可以看到新疆历史上的宗教信仰变迁过程(比如伊斯兰教其实并非新疆的本土宗教,起初甚至属于一种少数宗教,也是在历史发展的过程中才融入称为了新疆本地有一定影响力的宗教之一),以及多年前且至今保存良好的馕(没错,就是馕)。但是我们游览期间楼兰古尸区域在维护没有开展,以至于我们没有机会参观游览,有一点可惜。

其二是刀郎那一句“停在八楼的二路汽车”,这首歌里面的这一句歌词一直有很多的解读,但直到我眼瞅着居然真的有这个“景点”,才明白歌词背后的意义。虽然我不是刀郎的歌迷,但是能够在这样的一个场景里梦幻联动,还是挺有意思。

“八楼”其实是乌鲁木齐昆仑宾馆的所在地,作为当时乌鲁木齐的地标性建筑,一直被大家称为八楼(因为他的主楼一共有八层,而且是当时乌鲁木齐的最高建筑,最好的建筑),“2路汽车”则是当时贯穿乌鲁木齐市南北最主要的一条公交线路,到达所有地标目的地都可以搭乘 2 路汽车(有一点像是我印象中里兰州的 50 路)。

大概十来天的新疆之旅就是这样了,总得来说这一趟旅行是真的很享受,不仅一路上的风景非常舒服,令人眼花缭乱,另一方面来说有这样一个难得的时间享受在其中,充分领略祖国的大好河山,也是一件非常纯粹的事情。

但这一趟旅行我印象最深的还是蒋老师和我说的一段话,她大概是这样说的(原文很朴实,如果你觉得油腻可能是我做了一些画蛇添足的文学性改写):

“当你来到新疆,站在大草原上之后,你会发现自己忽然非常渺小。这种渺小会让你觉得那些原本规训了你让你习以为常或沉溺其中的问题都不再那么重要了。你可以听到风的声音,闻到雾的味道,面前是一望无际连接到雪山的草原山丘,背后是暧昧的发红但又可能说变就变的老天爷的脸色。那至少在这一刻,你可以不用那么焦虑,不用想那么多,只是待在当下找到身体里血液和呼吸流通活着的感觉,做自己就好”。

我觉得蒋老师还是很厉害的,有时候像诗人一样,有点牛。

读作なぎ(nagi),日语里「风平浪静」的意思。它是两个汉字的结合,一个汉字就包含了一个完整的词义。

中文世界里有一个耳熟能详的道理——树大招风。招风的树最怕的并不是叶散枝折,而是被连根拔起,所以其实在「树大招风」隐含了一个条件,就是树根不稳,否则招风也不会招来大家都「喜欢看到的剧情」。

没人喜欢「风平浪静」的生活,又不是那个人人向往在墨脱寻找希冀的文学年代——少年不知愁滋味,所以才需要不断地探寻「愁」到底是什么。倒不是吃饱了撑的,而是无论是剧情还是生活,风平浪静都意味着「死亡」。

静止 = 死亡

这是剧本创作里最基本的公式之一。


一对貌合神离的夫妻,彼此过着有「婚姻时差」的生活,妻子每天起床,丈夫还在另一个房间补眠,等她送完孩子上学买完菜回家后,丈夫已经悄无声息地出门工作了,和往常一样桌上给他准备的早餐连看都没看过一眼,所以她顺理成章地自己坐在桌边吃完了早餐——他们之间的默契已经到了妻子不用再做自己的早餐,因为她知道丈夫的这一份一定会被留下来……

完了?对剧情就到这里——这他妈什么剧情啊——她就这样认命了?丈夫在外面难道不是还有另一个家?妻子一定在谋划什么……如果剧情其实描述一个这样貌合神离的场景,没人会「接受」到此为止的,否则为什么要花时间去「照镜子」啊,我要的是能够代入一个角色,去对抗我已经失望的婚姻!对,这就是《消失的她》带来的后劲。

猫和老鼠之所以好看,就是因为他们每一天都在发生矛盾,两个人相安无事各自安好的生活谁要看啊!都说以和为贵,那是因为不想自己跟别人发生冲突,等到了别人身上的祸事儿,他们比谁都起劲儿呢!

在剧本结构里,前五分钟一定得表现出「死亡的气息」,比如直逼生命的冲突事件,或者就是已经处于「风平浪静」的生活,于是接下来一定会有天翻地覆的「圈套」让主角不得不进入到「转变角色」的剧情当中。

例如丈夫/妻子与情人遭遇车祸,留下了看似意外但是凶杀的谜团,甚至是发生车祸时妻子(直接的死亡)的嘴里正含着自己兄弟的老二(信任的死亡)——《美国众神》的开场;或者是妻子被代入了另一个欢愉的世界,在每天下午 3 点跟一个艺术家偷情享受丈夫无法提供的情绪价值和温暖(道德的死亡)——《昼顏~平日午后3点的恋人们~》的开场。


或许有人会站出来说:「我就是不想描写死亡,不想如此结构化地呈现剧本。」当然可以,并不是说任何一种形式的作品都需要按照公式呈现,只是这里有一个需要举一反三的点,就是所谓的「静止 = 死亡」就真的是「死亡」吗?

从剧本跳脱出来,现实的「静止」或许早就让我们麻痹了?

你现在可以站在窗户边,眺望一下附近的树丛,无论是自然形成的还是人工改造的,树林是需要空间的,这样的空间可以保证树与树之间的营养供给与光照需求。如果你能有幸看到那种夹在两栋楼房中间的树丛,就会发现它们往往会有枝细叶繁的情况。或是太密没有按照树木结构种下的树丛,也会因为要抢光照而出现比谁长得更高的情况。

树大招风,害怕招风的并不是那些彼此留下空间可以让根系与树干茁壮成长的树,而是那些还没有来得及扎根生桩就已经开枝散叶的树。

所以它们更需要「风平浪静」。

并不是说「风平浪静」就有错,也不能倒果为因地把期待「风平浪静」的树都定义为是经不起「树大招风」的。是否期待「风平浪静」是跟每个人的主体性相关的。简单来说,即内核越稳定的人,越不担心外界的冲突;而内核不稳定,或是主体性偏移到了「人设」上面时,就会越害怕外部冲突,哪怕是一个质疑都会让他们觉得被伤害。

那这样看来,那些在人生剧本里的「静止 = 死亡」到底是就该如此,还是当事人自己的选择,因为他们期待的就是让大家看到满枝花叶的盛景,而不是在风暴中经历「树大招风」的考验。


前段时间,写情小说的家伙跟我聊起,他身边有好几个年轻人都踏上了徒步环台湾岛的旅行。我查看了台湾对外公开的失业率、劳动力参与率、生育率等相关数据,觉得「时候到了」——即「静止 = 死亡」的剧情上演了。

同样的「时候」,是第二次世界大战之后,美国一群作家开启了一场文学运动,意在探索和影响二战后的美国文化和政治。这个时期的参与者们被称为「垮掉的一代」。他们探索的「意义」从现在来看其实就是所谓的「主体存在性」,人们需要将这些「意义」具象化成可以触摸到的丰碑与诗歌,所以在垮掉的一代里,有那么一群人都踏上了贯穿美国东西向的公路旅行——因为只有这样才能深刻地体会到存在的意义和方向,以及每一次完成跨越都是一次人生的里程碑。

关于台湾青年的迷茫感,我们还在讨论和研究,但这是一个不错的切入点,因为它具有很强烈的时代性。想要说的是,生命在于折腾这件事本身就是在对抗剧本结构所谓的「静止 = 死亡」,这种死亡是全方位的,最终会吞噬到一个人的存在性与意义感。

这是一片关于存在感与意义的树林,但是很快这里就会被那些枝细叶繁的树给侵占。在这些对抗「死亡焦虑」的旅途里,人们一开始追求的是对内的探索,徒步、骑行、三步一跪拜、此生必驾318……参与的人越多,就开始有了对外证明的规则。

想要在树林里争夺阳光,长出被人羡慕的花叶,就越需要对外索求「存在感」,于是探索变成了表演,意义变成了流量,又让这里的树林被内卷回了「静止 = 死亡」,让每一个打卡炫耀的人都可以获得那些曾经由别人努力的、对外证明过的标签,都贴回到自己身上。


但是,谁又不想看树大招风的剧情呢?只有这些被标签贴满的人,才渴望风平浪静吧!

注册一台阿里云小主机用于 WordPress 教程编写

本站目前托管在阿里云的 ECS 服务器上,基本配置如下:2 核 CPU、4GB RAM、40GB + 10GB SSD 存储和 100M 宽带(按量计费)。目前该服务器上运行着三个主要网站,日均总流量不到 2000 PV,此外还支持几个边缘业务应用和 3 个 Docker 容器,服务器还承载着 Syncthing 文件同步应用和 Frp 内网穿透服务。

尽管在瞬时高并发时系统会出现一定卡顿,但总体运行非常流畅。服务器当前状态如下:

本站服务器状态监测
本站服务器状态监测

最近,我决定花一些时间将搁置已久的草稿《..... [ 阅读全文 ]


原文链接: https://www.shephe.com/website/wordpress-test-host/
版权声明: Kevin's Space 版权所有,转载请用明链标明本文地址
本站相关: 随机文章 | 站长微博 | 关于本站 | 联系站长 | 捐助作者

💾

❌