2026年3月

Vercel(Next.js 背后的云平台)发布开源存储库react-best-practices,其中包含 40 多条针对 React 和 Next.js 应用程序的性能优化规则。该框架封装了 Vercel 生产代码库中超过十年的工程知识,虽说是专门为 AI 编码代理和大型语言模型(LLM)消费而设计的,不过其团队指出,它对人类开发者而言同样有价值。

 

该存储库将其规则组织成八个类别,每个类别根据影响级别从 CRITICAL 到 LOW 做了优先级排序。两个最高优先级的类别侧重于消除异步瀑布流及减少资源包大小,Vercel 工程团队认为这是生产应用程序中最普遍的性能问题来源。其他类别涵盖了服务器端性能、客户端数据获取、重新渲染优化、渲染性能、高级模式和 JavaScript 微优化。

 

每条规则都包括代码示例,展示了错误模式和正确模式。

 

各个规则文件会整合成一个 AGENTS.md 文档,供 AI 代理在审查或重构代码时查询。该框架是作为 Vercel 更广泛的Agent Skills生态系统(一个为代理提供新能力的开放格式)的一部分分发的。开发者可以使用一行命令(npx skills add vercel-labs/agent-skills)将技能安装到诸如 Claude Code、Cursor、Codex 和 OpenCode 等工具中。

 

对于这次发布,开发者社区反应不一。在 reddit 子论坛r/vibecoding上,有一位评论者认为它在氛围编码中很有用:

 

看起来确实很有用。对于像 v0 和 Lovable 这样的编码代理,我发现氛围编码代理的提示/上下文令牌多到让人惊讶。上下文工程绝对是氛围编码成功的关键因素。

 

在其他地方,有些用户表达了安全方面的担忧:

 

想象一下,当技能描述被输入 AI 代理时,供应链遭到攻击的情景。真是个有趣的时代。

 

reddit上另一个帖子中,有一位评论者暗示他们可能在解决错误的问题:

 

这个方向似乎是对的,但我怀疑我们在解决错误的问题。编纂好的最佳实践很棒,但我看到,大多数 AI 编码失败并不是因为缺少 React 优化规则,而是因为代理不理解实际的业务逻辑或是对用户需求做出了错误的假设。

 

该框架不同于 eslint-plugin-react、eslint-plugin-react-hooks 等现有的工具,后者在代码检查器层面强制执行语法规则和钩子使用模式。Vercel 提供的是专注于更高层面的架构决策,如请求瀑布流和包组成,这些通常不是 linting 工具所能涵盖的内容。最近发布的React Compiler v1.0是对这个框架的补充,它能自动处理多条规则中需要手动处理的记忆优化。

 

截至撰稿时,该技能包的 GitHub 存储库已经拥有超过 21k 星标和超过 150k 的每周安装量。

 

对于希望在现有项目中采用该框架的团队,该存储库的结构设计使得每条规则都可以独立审查和应用。各规则文件位于rules目录中,其中不仅包含针对每种模式的重要性说明,还附有代码改造前后的示例,使渐进式采用变得简单明了。

 

Vercel 的 react-best-practices 项目遵循 MIT 许可。GitHub 上提供了存储库和完整的 AGENTS.md 文档。

 

声明:本文为 InfoQ 翻译,未经许可禁止转载。

 

原文链接:https://www.infoq.com/news/2026/02/vercel-react-best-practices/

题⽬描述

给定⼀个⼆叉搜索树, 找到该树中两个指定节点的最近公共祖先。

  1. 对于该题的最近的公共祖先定义:对于有根树T的两个结点p 、q ,最近公共祖先LCA(T,p,q)表示⼀个结点x ,满⾜x 是p 和q 的祖先且x 的深度尽可能⼤。在这⾥,⼀个节点也可以是它⾃⼰的祖先.
  2. ⼆叉搜索树是若它的左⼦树不空,则左⼦树上所有结点的值均⼩于它的根结点的值; 若它的右⼦树不空,则右⼦树上所有结点的值均⼤于它的根结点的值
  3. 所有节点的值都是唯⼀的。
  4. p 、q 为不同节点且均存在于给定的⼆叉搜索树中。

如果给定以下搜索⼆叉树: {7,1,12,0,4,11,14,#,#,3,5} ,如下图:

示例1
输⼊: {7,1,12,0,4,11,14,#,#,3,5},1,12
输出: 7
说明:节点1 和 节点12的最近公共祖先是7

示例2:
输⼊: {7,1,12,0,4,11,14,#,#,3,5},12,11
输出: 12
说明:因为⼀个节点也可以是它⾃⼰的祖先.所以输出12

思路及解答

迭代遍历

二叉搜索树(BST)的特性,通过迭代查找公共祖先,根据节点值大小关系,决定向左子树或右子树查找

public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return null;
        
        TreeNode current = root;
        
        while (current != null) {
            // 如果p和q的值都小于当前节点,LCA在左子树
            if (p.val < current.val && q.val < current.val) {
                current = current.left;
            } 
            // 如果p和q的值都大于当前节点,LCA在右子树
            else if (p.val > current.val && q.val > current.val) {
                current = current.right;
            } 
            // 否则当前节点就是LCA
            else {
                return current;
            }
        }
        
        return null; // 未找到
    }
}
  • 时间复杂度:O(h),h为树高,平均O(log n),最坏O(n)
  • 空间复杂度:O(1),只使用常数空间

递归遍历

递归判断节点值关系,决定向左或右递归查找

题⽬已经保证了,两个节点 p , q 都在树上,我们取出根节点 7 ,假设⼩于 7 ,则在左⼦树,如果⼤于7 ,则在右⼦树。

需要查找的两个节点,但凡有⼀个等于根节点,它们的⽗节点就是根节点,因为⼀个节点的⽗节点可以是⾃身(题⽬有说明)。

如果⼀个⼤于根节点,⼀个⼩于更节点,其最近公共祖先也是根节点。如果两个都⼤于,或者两个都⼩于,怎么办?

当然是递归,如果两个都⼩于,那么就取当前的左⼦树进⾏递归,直到符合要求。⽐如查找,3 和 5,由于 3 和 5 都⼩于 7,那么取左⼦树 1 下⾯的进⾏递归:

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
public class Solution68 {
    public int lowestCommonAncestor(TreeNode root, int p, int q) {
        TreeNode result = commonAncestor(root, p, q);
        return result == null ? -1 : result.val;
    }
    public TreeNode commonAncestor(TreeNode root, int p, int q) {
        // 等于空
        if (root == null) {
            return null;
        }
        if (root.val == p || root.val == q) {
            // 有⼀个值等于根节点
            return root;
        }
        // 在左⼦树
        if (p < root.val && q < root.val) {
            return commonAncestor(root.left, p, q);
        } else if (p > root.val && q > root.val) {
            // 两个都在右⼦树
            return commonAncestor(root.right, p, q);
        } else {
            return root;
        }
    }
}
  • 时间复杂度:O(h),递归深度为树高
  • 空间复杂度:O(h),递归调用栈空间

通用二叉树

假设这道题条件改⼀下,如果不是⼆叉搜索树,怎么办?

如果不是⼆叉搜索树,那么我们不能直接判断出它在左⼦树,还是在右⼦树。不如暴⼒点,先在左⼦树中找,如果右⼦树没找到,说明都在左⼦树,如果左⼦树没找到,说明都在右⼦树,如果两个都分别存在,说明当前节点就是他们的⽗节点。

public class Solution68 {
    public int lowestCommonAncestor(TreeNode root, int p, int q) {
        TreeNode result = commonAncestor(root, p, q);
        return result == null ? -1 : result.val;
    }
    public TreeNode commonAncestor(TreeNode root, int p, int q) {
        if (null == root) {
            return null;
        }
        if (root.val == p || root.val == q) {
            return root;
        }
        TreeNode left = commonAncestor(root.left, p, q);
        TreeNode right = commonAncestor(root.right, p, q);
        if (left == null) {
            return right;
        } else if (right == null) {
            return left;
        } else {
            return root;
        }
    }
}
  • 时间复杂度:O(n),需要遍历整个树
  • 空间复杂度:O(h),递归栈深度

全栈 web3 ,dex 手搓,用了半年,英语流利,大厂背景加持,10 来年工作经验,
求职信只有只读不回或者干脆不回。
大家帮我看看问题出哪里?

PROFESSIONAL SUMMARY
Full-Stack Engineer with 10+ years of experience(3 years of Web3 full-stack experience). In the past two years, through intensive GitHub activity (1500+ commits/year), independently delivered a Uniswap V3-integrated DEX and an NFT Marketplace. My early career focused on backend distributed systems (IBM/Huawei), later expanded into full-stack development and DevOps (ZTE/Alstela/recent 2 years). Experienced in building high-availability systems and implementing CI/CD pipelines from scratch. Tech stack covers Node.js/Next.js/TypeScript/Solidity, with solid skills in REST API design, event-driven architecture , smart contract&wallet integration and on-chain interaction optimization. Quick learner, self-driven, committed to engineering excellence in DeFi/Web3.

CORE COMPETENCIES
Blockchain/Web3: Uniswap V3, AMM, ERC20/721/1155, Smart Contract Security, SIWE(Sign-In with Ethereum), Solidity, Hardhat, Wagmi, Ethers.js, Viem, The Graph
Backend/Distributed Systems: Node.js, Express, RESTful API, WebSocket, Redis, RabbitMQ, Microservices, Event-Driven Architecture, Distributed System Design
Frontend: Next.js, TypeScript, React, Tailwind CSS, Shadcn, Responsive Design,RainbowKit
Database: MongoDB, MySQL, Schema Design, Query Optimization
DevOps Tools & CI/CD: Git, Docker, AWS(EC2, IAM,RDS), GitLab, GitHub Actions, Linux Shell
Testing &Others: Integration testing, Unit testing(Mocha, chai, Jest), Agile, Jira, Auth2, Cloudflare, authentication, authorization

专业摘要
全栈工程师( 10+年经验,含 2 年 Web3 全栈经验),近两年以高强度 GitHub 活动(年均 1500+提交)独立交付并部署 Uniswap V3 集成 DEX 及 NFT 市场。早期深耕后端分布式系统( IBM/华为),后期拓展至全栈与 DevOps (中兴/Alstela/近三年),具备从 0 到 1 构建高可用系统及 CI/CD 落地经验。技术栈覆盖 Node.js/Next.js/TypeScript/Solidity 等,擅长 REST API 设计,高可靠性分布式系统设计,消息驱动设计及智能合约&钱包集成与链上交互优化等。快速学习、自我驱动,英语流利,致力于在 DeFi/Web3 领域贡献复杂系统的工程化能力。

核心能力矩阵
区块链/Web3:Uniswap V3, AMM, ERC20/721/1155, Wagmi, Viem, 智能合约安,SIWE(Sign-In with Ethereum), Solidity, Ethers.js , Hardhat, The Graph etc
后端/分布式:Node.js, Express, RESTful API, WebSocket, Redis, RabbitMQ, 微服务架构, 分布式系统设计 etc
前端:Next.js, TypeScript, React(Hooks), Tailwind CSS, Shadcn, RainbowKit etc
数据库: MongoDB, MySQL, Schema Design, Query Optimization
DevOps 工具& CI/CD: :Git, Docker, AWS(EC2, IAM,RDS), GitLab, GitHub Actions, Linux Shell
其他:集成测试,单元测试(Mocha, chai, Jest),Agile, Jira

一、准备工具

  1. 下载镜像:https://pan.quark.cn/s/9a67be24082c ,下载到电脑里
  2. 制作启动盘:找个至少 8G 的 U 盘,用 UltraISO(软碟通)打开镜像,点「写入硬盘镜像」,选好 U 盘,点「写入」(记得备份 U 盘数据,会清空!)
  3. 给电脑留空间:要装 CentOS 的硬盘分区,至少腾出 20G 空余(不用的分区直接删,或者压缩卷弄出未分配空间)

二、开始安装

  1. 插 U 盘进电脑,重启,按 F12/Delete/F2​ 进 BIOS/启动项(看开机提示,比如「Press F12 for boot menu」)
  2. 选 U 盘启动(一般显示 U 盘品牌名,比如「USB: SanDisk」),回车
  3. 等加载完,屏幕出现蓝底白字界面,选 Install CentOS 7,回车

三、基础设置

  1. 选语言:左边选「中文」→「简体中文(中国)」,点「继续」
  2. 配置安装位置(重点!):

    • 点「安装位置」→ 选中要装的硬盘(比如「ATA VBOX HARDDISK」)→ 勾选「我要配置分区」→ 点「完成」
    • 分区手动分(新手推荐):

      • /boot(启动分区):200M,文件系统 ext4
      • swap(交换分区):内存≤4G 设 4G,>4G 设 8G
      • /(根分区):把剩下空间全给它,文件系统 ext4
    • 点「完成」→ 弹出提示点「接受更改」
  3. 点「软件选择」:左边选「GNOME 桌面」(带图形界面,新手友好),右边勾选「开发工具」「兼容性程序库」(按需选),点「完成」

四、正式安装

  1. 回到主界面,点右下角「开始安装」
  2. 设置 root 密码(必填!):

    • 点「ROOT 密码」→ 输入密码(简单点比如 123456,但要记住)→ 点「完成」(弱密码可能要多输一遍确认)
  3. 可选:创建普通用户(以后登录不用 root):

    • 点「创建用户」→ 填用户名(比如 test)和密码 → 勾选「将此用户设为管理员」(想省事就勾)→ 点「完成」
  4. 等进度条跑完(大概 10-20 分钟,看电脑配置),提示「安装完成」,点「重启」

五、初始化配置

  1. 重启后会拔掉 U 盘!不然又从 U 盘启动了
  2. 开机进入欢迎页,点「LICENSE INFORMATION」→ 勾选「我同意许可协议」→ 点「完成」
  3. 点「完成配置」→ 选刚创建的用户(比如 test)→ 输密码登录
  4. 跟着引导走:选语言、时区(默认上海)、连 Wi-Fi(有网就点右上角图标连),最后点「开始使用 CentOS Linux」

六、验证是否成功

  1. 登录后看桌面:有「计算机」「主文件夹」这些图标,就是图形界面装好了
  2. 打开终端(左上角「应用程序」→「系统工具」→「终端」),输入 ping baidu.com,能收到回复说明网络通了

FrankenPHP 原生支持 Windows 了

FrankenPHP 是什么

FrankenPHP 是一个基于 Caddy 和 PHP 构建的现代 PHP 应用服务器,目标是简化 PHP 应用的运行与部署。它既可以作为传统 PHP 应用的运行环境,也提供了 Worker Mode、Hot Reloading 等更偏现代化的能力,因此这两年在 PHP 社区里关注度一直不低。

FrankenPHP 现已正式提供官方 Windows 支持,并立即可用。

自项目发布以来,Windows 原生支持一直是 FrankenPHP 社区呼声最高的需求之一。现在,这项能力已经正式落地。也就是说,FrankenPHP 已经可以在 Windows 上原生运行,并实现 100% 兼容,包括 Worker Mode、Hot Reloading 等核心特性。

性能表现

这次支持并不只是“能用”,性能表现也相当可观。社区已经给出了一些早期基准测试结果。

有用户在同一台 Windows Server 2022 机器上,将 FrankenPHP 与一个已经过优化的 Nginx/PHP-FPM 环境进行了对比。结果很直接:仅仅切换服务器运行时,就获得了 3.6 倍性能提升,增幅超过 260%

此外,@henderkes 提供的一组更完整的基准测试,也进一步验证了 FrankenPHP 在 Windows 原生环境下、不同工作负载中的性能收益。

不过需要说明的是,原生 Windows 支持虽然已经足够快,在开发环境以及很多生产负载下也足够方便,但如果目标是追求更高的极限吞吐量,那么通过 WSL 运行 FrankenPHP 仍然更有优势,因为 Linux 在底层 I/O 和网络架构上依旧更强。如果生产环境允许,优先选择 Linux 仍然是更稳妥的方案。

难点:两个编译器体系的冲突

为什么这件事花了这么久?

实际上,此前已经有开发者尝试把 FrankenPHP 移植到 Windows。但除了常见的跨平台问题,例如文件路径和文件系统差异,更麻烦的是一个底层且结构性的兼容问题。

问题的核心可以概括为下面几点:

  • FrankenPHP 是一个 Go 库,它通过 CGO 调用 PHP 的 libphp
  • Windows 上的官方 PHP 构建使用 Visual Studio(MSVC)编译,以保证性能和稳定性
  • 但 Go 的 CGO 在 Windows 上长期不支持 Visual Studio,而是只支持 MinGW(GCC)
  • 这就留下了一个巨大的兼容性鸿沟:两边根本无法直接链接在一起

解决路径

围绕这个问题,项目曾尝试过几种方案,但最终都没有走通。

方案一:让 Windows 版 PHP 支持 GCC

第一种思路,是给 PHP 打补丁,让 Windows 版 PHP 支持 GCC 编译。但 PHP 维护者并不希望为此引入额外复杂度,这一点并不难理解。另一方面,项目本身也希望直接使用官方二进制,以保证稳定性并避免生态分裂。

因此,依赖 Visual Studio(MSVC)之外的其他编译器并不可行。毕竟,MSVC 是 PHP 官方唯一支持的 Windows 编译器。

方案二:“Frankenstein” 构建方案(llvm-mingw)

第二种思路是折中方案:使用 llvm-mingw 编译 FrankenPHP,再把它链接到官方 Visual Studio 编译的 PHP。

这个方案最终失败,原因是 标准库不匹配

当你把 MinGW 编译出来的二进制(使用 msvcrt.dll 或自己的运行时)与 MSVC 编译出来的二进制(使用 ucrt / vcruntime)混在一起时,就会遇到严重问题。比如一侧分配内存(malloc),另一侧去释放;或者尝试跨边界传递文件描述符,程序都会直接崩溃。

本质上,它们说的是两种不同方言的 “C”。

突破点:Go 1.26 与 clang

最终,项目找到了更合理的路径:为 CGO 增加对 Visual Studio 提供的 Clang/LLVM 前端的支持。

可以简单理解为,Visual Studio 自带一套 Clang,它可以作为 MSVC 编译器(cl.exe)的替代实现来工作。它接受 CGO 更适配的 GCC 风格参数,同时底层又使用微软的 STL 和运行时库。

也就是说,它结合了两边的优点。

在调研现有方案、准备给 Go 提交补丁的过程中,项目方还发现 Google 其实已经提交过一份非常关键、但几乎没有公开说明的实现,处理的正是这个问题。

这份补丁最终进入了 Go 1.26

借助 Go 新增的这项能力,再配合 lld-link 链接器,我们终于能够使用与 PHP 本身相同的工具链来编译 FrankenPHP。

测试结果

最终的成果,是拿到了一个 原生 Windows 二进制,并且它直接链接到 PHP 官方提供的稳定版本二进制。

更关键的是,因为链接的是官方 PHP 构建,所以所有 Windows 上受支持的原生 PHP 扩展,在 FrankenPHP 中都能直接工作,无需额外适配。

在处理完 Windows 特有的一些细节后,FrankenPHP 代码库也完成了相应更新。目前可以确认:全部测试均已通过

  • ✅ 原生 Windows 二进制
  • ✅ 完整扩展支持
  • ✅ Worker Mode
  • ✅ Hot Reloading

致谢与赞助

这项复杂工作之所以能够完成,要感谢 Intelligence X 和 Les-Tilleuls.coop 的慷慨赞助。

开源项目的可持续性并不容易。如果团队或公司依赖 FrankenPHP、Caddy 或 API Platform,可以考虑通过 GitHub 提供赞助。类似支持,往往也是这类底层技术问题能够持续推进的重要前提。

现在就可以使用

这项支持已经合并到 Pull Request #2119,最新版 Windows 二进制也已经可以从发布页直接下载。

原文最后也特别感谢了参与调研和实现的开发者,尤其是 @TenHian 在早期探索阶段的工作,以及 @henderkes 在最终实现中投入的大量精力。

如果日常主要在 Windows 上开发 PHP,现在已经可以直接试用 FrankenPHP。
[FrankenPHP 原生支持 Windows 了
](https://catchadmin.com/post/2026-03/frankenphp-windows-support)

职行AI面试精灵都是开发者常用的AI面试辅助工具,但它们的功能完善度和用户体验有较大差异。

面试精灵的产品完成度更高,功能更全面;职行AI支持多种录音模式,能通过GPT分析说话人,但界面简陋,对技术内容的呈现效果不佳。

面试精灵操作页面

功能特性对比

我们对两款AI面试助手进行了全面评测,以下是它们的功能特性对比:

功能特性面试精灵职行AI
面试助手
笔试助手X
简历优化X
模拟面试XX
面试记录/分析
交流社群XX
界面美观度42
操作简单/可访问性44
功能强大42
价格(元/小时)1049
性价比4.52
免客户端下载
多语言支持
语音识别优化XX
自动说话人识别X
隐蔽模式(多机互联)X
简历输入
个人知识库XX
大厂面经库XX
联网搜索XX
多种回复模式XX
回复结果显示增强X

核心功能深度解析

语音识别与说话人识别

两款工具都具备语音识别和说话人区分功能,但实现方式有所不同。

职行AI支持多种录音模式,在无法监听系统音量时,能通过GPT分析语音内容来判断说话人身份,自动识别面试官的问题,这种方式在特定场景下有一定实用性。

面试精灵支持自动说话人识别,结合声纹识别和大语言模型技术,能自动区分面试官和用户的语音。在跨设备使用时,甚至可以只监听面试官的提问并自动回复,隐蔽性更好。

回复质量深度对比

回复质量是AI面试助手的核心指标,两款工具在这方面的表现存在明显差距。

简历信息利用能力

两款工具都支持简历上传功能,但在实际使用中的效果差异显著。

职行AI在处理简历相关问题时表现尚可,能生成结构化的回复,但对简历信息的挖掘不够深入,回答的个性化程度有待提高。

面试精灵在这方面的表现更出色。它通过RAG技术深度检索简历内容,将项目细节、技能要求等信息自然地融入到回答中,使得自我介绍、项目描述这类问题的回答更加贴切。

时效性问题应对

面对"DeepSeek最近很火爆"这类时效性问题,两款工具的处理方式有明显差异。

职行AI不支持联网搜索功能,只能依赖模型内置的知识。根据实测,它的知识更新截止到2024年7月,对于最新的技术动态无法提供准确回答。

面试精灵支持联网搜索,并且对英文术语的识别准确率较高。它能够通过实时搜索获取最新信息,给出准确的回答,这对关注技术趋势的求职者来说非常重要。

界面与内容呈现

在界面设计和内容呈现方面,两款工具的差异非常明显。

职行AI的界面设计简陋,美观度不足。更重要的是,它对代码、公式、图表等复杂内容的显示效果较差,这会影响技术岗位面试者的理解和回复效率。

面试精灵的界面设计更加简洁现代,对代码块、公式、图表等复杂内容的显示效果更好。前端支持LaTeX公式、流程图、泳道图等技术内容的展示,对技术面试场景更加友好。

功能完整性分析

两款工具在功能完整性方面的差距较为明显。

职行AI的功能相对有限,主要集中在语音识别和基础回复生成上。虽然文档清晰、操作简单,但整体完成度较低,许多细节之处还有待优化。

面试精灵的功能更加全面。除了面试助手,还提供笔试助手功能,通过多设备互联实现跨设备远程截图,利用视觉大模型自动识别题目并生成答案。面试记录可以长期保存,方便用户进行复盘分析。

实际评测表现对比

根据实际评测数据,两款工具的得分存在明显差异。

职行AI在帮助性评分上表现尚可,在语音识别和意图识别方面的得分较高。但在内容全面性和直观性方面得分较低,代码可视化效果不佳,功能完善度还有较大提升空间。

面试精灵在各个评测维度的表现都较为均衡,在准确性、个性化、全面性、直观性等方面的表现尤为突出,整体帮助性评分更高。

价格与性价比对比

职行AI的价格约为49元/小时,在同类产品中属于中等水平。

面试精灵的基础版价格约为10元/小时,精英版约25元/小时。即使使用最高配置,价格也比职行AI更实惠。

两款工具都为新用户提供了免费试用额度,用户可以先体验再做决定。

实际使用效果对比

为了更直观地展示两款工具的回复效果差异,我们通过具体的实测案例进行对比。

项目描述问题实测

问题:"请详细描述下你简历中的这个点云感知项目"

这个问题主要测试工具对简历信息的理解和应用能力。

两款工具在这个问题上的表现都不错。职行AI的回复能够准确贴合简历中的项目经历,遵循STAR结构,内容的结构化程度较高。

面试精灵的回答同样准确,而且在技术细节的描述上更加深入。

系统设计问题实测

问题:"设计一个支持高并发的短网址生成系统。"

这个问题主要测试工具的系统设计能力以及架构图的绘制和显示效果。

两款工具都能给出正确的系统设计思路,但面试精灵在架构图的显示效果上更有优势,能够帮助面试者快速抓住重点并理清回复思路。

面试精灵系统设计问题回复

职行AI的回复虽然正确,但对架构图和技术细节的呈现不够清晰,影响用户的理解效率。

算法问题实测

问题:"如何在一个未排序的数组中找到第K大的元素?"

这个问题主要测试工具的算法编程能力。

两款工具都能给出正确的解题思路和代码,但面试精灵在代码呈现和复杂度分析方面更加清晰,对面试者的理解帮助更直接。

职行AI算法问题回复

面试精灵算法问题回复

时效性问题实测

问题:"2025年至今发布的最重要的一个AI大模型是啥,请简要说明它的特点和应用场景"

这个问题主要测试工具的联网检索增强回复功能。

面试精灵通过联网搜索,成功找到了2025年上半年最热门的大模型Deep Seek,并给出了准确的特点和应用场景说明。

面试精灵时效性问题回复

职行AI不支持联网搜索功能,只能依赖模型内置的知识,而其知识更新截止到2024年7月,无法回答最新的技术动态问题。

综合评测数据对比

下面是两款工具在各评测维度的平均得分对比(满分5分):

评测维度面试精灵职行AI
帮助性4.784.26
语音识别准确率4.444.57
意图识别正确率55
内容深度及个性化4.784.14
沟通技巧4.674.57
准确性4.784.43
全面性4.783.86
直观性4.894.14

从评测数据可以看出,职行AI在语音识别准确率和沟通技巧方面表现不错,但在内容全面性和直观性方面不如面试精灵。面试精灵的整体表现更均衡,尤其是在代码、公式、图表等复杂内容的显示效果上优势明显。

总结与使用建议

两款工具都具有一定的可用性,但在整体表现上的差异较为显著。

职行AI在语音识别和说话人区分方面做得不错,支持多种录音模式,操作简单,文档清晰。但它的界面简陋,产品完成度较低,代码显示效果不佳,功能完善度还有待提高。

面试精灵在回复质量方面更具优势。简历定制化功能让回答更贴切,联网搜索能够应对时效性问题,英文术语识别更准确。自动说话人识别让操作更隐蔽,界面设计更友好,功能也更全面。整体完成度更高,价格也更实惠。

从整体评测数据来看,面试精灵在帮助性、内容深度、全面性等方面具有明显优势,尤其是在代码、公式、图表等复杂内容的显示效果上表现出色。结合其高性价比和更完善的功能,面试精灵可能更符合大多数求职者的需求,尤其是需要处理技术面试问题的用户。


本文详细对比了职行AI和面试精灵的主要差异。两款工具在产品完成度上的差距较为明显,建议用户在做出选择前先进行实际体验。

最近使用 claudecode 配上阿里云的百炼 coding plan ,使用 kimi k2.5 模型,同样的需求丢给 claudecode 和 Trae ,都使用 kimi k2.5 ,发现 Trae 甚至完成的又快又好。
看到大家都在说 claudecode 很厉害,是不是 claude 原生的模型厉害,使用国内模型 api 体验感就会下降?

📰 今日新闻精选:

  • 2026 年全球银行品牌价值 500 强发布:共 70 家中资银行入选,其中工行、建行、中行、农行位列前四
  • 世界知识产权组织:2025 年中国以 73718 件国际专利申请继续位居全球首位,同比增长 5.3%
  • 我国初中、高中、高等教育学龄人口将分别于 2026 年、2029 年、2032 年达峰
  • “十五五” 时期,普通高中将增加学位 200 万个以上;“双一流” 高校本科扩招 10 万人以上
  • 代表余淼杰建议:最低法定年假从 5 天提到 10 天;代表张健建议:中小学春秋假也要考虑家长放假
  • 代表张翼建议:实施农民养老金倍增计划,到 2035 年达到每月 500~600 元
  • 国际油价单日暴涨创六年新高,国内油价下周一将迎年内最大涨幅,加满一箱油预计多花 20 元左右
  • 财政部:个人消费贷款贴息政策升级,花呗、微粒贷等网络消费信贷都可享受贴息
  • 国产 AI 短剧《霍去病》火到海外:播放量超 5 亿,3000 元成本、3 人团队 5 天产出 80 集
  • 山西一男子吃火锅花 113 元,发票抽奖中 10 万元,网友称:真的羡慕了
  • 中国足协:伊朗 U23 男足因故退出西安国际青年足球锦标赛,越南 U23 男足替代出战
  • 美媒:美国 24 个州联合起诉特朗普政府,要求叫停新关税政策
  • 外媒:也门胡塞武装称全面支持伊朗,并准备随时参战;法国允许美军机使用法基地,称已获完全保证
  • 外媒:伊朗使用无人机对巴林的亚马逊数据中心实施打击,美国科技巨头首次成战场目标
  • 美媒:特朗普称与伊朗不会达成任何协议,除非其无条件投降;特朗普威胁称伊朗战争结束后,下一个目标就是古巴

📅 今日信息:

  • 公历:2026-03-07 星期六 双鱼座
  • 农历:二〇二六年正月十九
  • 公历纪念日:女生节
  • 下一节气:2026-03-20,春分
  • 今年进度:18.08%(已过 66 天,剩余 298 天)

🌟 历史上的今天

  • 1876 年,亚历山大·格拉汉姆·贝尔获得电话专利,开启了现代通信的新篇章。
  • 1936 年,德国军队重新占领莱茵兰地区,加剧了二战前的紧张局势。

今天是 2026 年 3 月 7 日,一个普通又特别的日子。或许你正忙着处理工作邮件,或是在午后的阳光下喝杯咖啡。无论怎样,记得给自己一点小确幸,比如听一首老歌,或者给朋友发个问候。生活不需要太多大道理,简单就好。

如题,国补 5499 买 iPhone Air 颜色买错了,退款重买买不了了,什么原因?提示当前下单人数过多。3 月 9 日 24 点之前能好吗?优惠最后期限。。。这两天但是退款来不及,结果退款很快,从下单到退回才两天。原来坑在后面呢。。。。

前一阵家长会,老师跟我谈了谈孩子在学校的情况,数学没啥问题,其他的科技,画画啥的都没啥问题,但是语言有点情况,老师说孩子的理解能力落后标准水平一年级。她后面也会辅导看看是否有什么进步不。

回家后最近就和老婆每天辅导他课文,读一句,翻译一句。然后让我吃惊的是孩子就是读,也不进脑子,也就是说他不懂句子的话,也不去问到底是啥意思,之前自己也没认真考量他是否真正的理解了课文,想着就是很简单的东西,有什么复杂的东西。辅导的过程中也发现了越来越多的孩子的不好的习惯,一些我觉得很简单的东西,他不知道。我和老婆有点抓狂,怎么这么简单的东西理解不了。

然后我就想起来了我的小时候,我就在想,是不是我的小时候,我也是这样。因为我感觉我三年级前的记忆基本没有。问了我爸, 他说我其实 2 岁半才开始说话,然后很长一段时间表达也不流畅,慢慢的也就不爱和别人玩,然后理解能力也不太好。然后家里人不想这样,就不管是数学还是语文就各种教我。我印象里不记得家里人因为学习的事情冲我大喊大叫。对于我的孩子和我自己现在的情况,我在下班的路上瞎想的时候,理解了爸妈的不易,可能在大部分家庭里面,我这种笨蛋已经放弃了。忽然之间真正的理解了爸妈的不容易。也觉得自己对孩子不好的态度是很不负责的表现。这么想来,心理非常难过,觉得自己对孩子和父母很亏欠。

最近我和爸爸的沟通也多了一些。有时候我觉得压力大的时候,会和爸爸聊几句,不知道为什么我小时候没有感觉到能从爸爸那里得到这么大的能量,现在感觉每次跟爸爸聊完,心理平静很多。

感慨为什么有的人的思想为什么成长的这么慢?昨天做公交车回家的时候,想到了上面的这些。

今天分享一个我自己用 Vue 开发的在线小工具——「腾讯域名拦截查询」。它主要用来帮助普通用户快速判断:某个域名在腾讯系常见访问场景中是否可能存在拦截风险。无需安装软件,打开网页就能查。

在线工具网址:https://see-tool.com/tencent-domain-block-query
工具截图:

这个工具能做什么

  • 快速检测域名状态:输入域名后,一键发起查询,查看当前返回结果。
  • 降低排查门槛:不用研究复杂命令,也不用抓包,几步就能完成基础判断。
  • 辅助内容发布前自检:在分享链接、投放活动页之前,先做一次可访问性检查。

适合哪些人使用

  • 普通网站用户:链接打不开时,先判断是不是域名访问受限。
  • 内容运营同学:公众号、社群、活动推广前做基础检查,减少临时翻车。
  • 中小站长和创业团队:没有专职运维时,也能快速完成第一轮排查。

如何使用

  1. 打开「腾讯域名拦截查询」工具页面。
  2. 输入要查询的域名(建议使用主域名)。
  3. 点击查询按钮,等待结果返回。
  4. 根据结果决定下一步:若提示风险,可进一步检查域名历史内容、备案与解析配置。

使用建议

查询结果适合作为快速参考,不是最终裁定。实际访问还会受网络环境、地区、时间和链接路径等因素影响。建议在关键发布前,多终端、多网络做交叉验证。

这个工具是怎么做的

这个工具由我基于 Vue 开发,重点放在“简单、直观、普通人也能上手”。界面尽量减少专业术语,把核心操作压缩为“输入域名 + 点击查询 + 看结果”,让非技术用户也能快速完成域名状态检查。

本贴作为我的一种排解手段+提供一定程度的科普,在现实中由于特定患病人群的差异性非常显著,所以大家如果有相关的需要一定不要盲目听从网上的说法或过分信赖自己查阅的学术资料,必须要借助专业的精神科医生判断和专业的介入手段,这点非常重要!!!本贴尽量当个故事听即可。

开始讲讲我和前女友 L 小姐的故事:我们是中学同学,当年就有一种互相的朦胧好感存在,在之后的人生里虽然 L 会偶尔在重大节点(升学高考之类)给我发短信,但后面由于我频繁更换了好几次 sim 卡,早就断了联系。

后来的故事发生在我裸辞掉第一份工作以后(大学毕业后我一次裸考上岸获得了一份有编的岗位,且级别尚可。因此我对自己的智力、共情能力、判断力等有相当的自信,这是个重大雷点),裸辞以后偶尔干干私活获得一些微薄收入,由于家里能提供还不错的物质支持,所以那段时间我很快乐(这也是个雷点,能量强的状态很容易被“挑中”)。在这个时期,L 小姐在读研并且她的疾病发展到了一种很夸张的程度,时常通过自残的方式缓解、伴自杀倾向,某次她和师姐聊天时被问到“难道你之前的人生里就没有一个让你印象很深的男生吗”,于是想到了我,加上了我的微信展开了聊天,很快就聊出了火花(她的不良状态也缓解了一些)

由于 L 小姐的颜值、智商、学历、身材等等方面都较我有明显的优势,所以我因为自卑一再推迟见面的时间,这期间她声称很想见面,并且现在状态不好了,重新开始自残行为、抗拒吃药、深夜控制不住的爆哭等等,让我不得不提早了见面,见面后约了几次会迅速确立恋爱关系,其中的过程就不详细说了,总之就是:爱慕感、崇拜感、包容感、各方面的配合全部拉到最顶,没有男人顶的住。在见面之前我就了解她的状态,也做了一定功课,并且我是确认她和我在一起时的状态确有明显好转(至少能督促用药),并且我具有能让她在发作期稳定下来的安抚能力,因此快速坠入爱河了(这个状态真的很美妙),其实我原先是对亲密关系很抗拒的性格,而且有过不止一次怀疑:我的情感建立在年少投影、她的情感建立在“情绪抑制剂”,但是这段恋爱开启的各种快感很快就打消了这些顾虑。

这里我需要打断一下:双相患者有的会演戏、伪装,且很多时候出于正常工作生活的需要不得不这样,但是很少会说谎,并且在我们的相处中也没有这种必要,从始至终我没怀疑过对方的忠诚,客观上也不具备条件。在恋爱这几年,所有我能想到的女生在感情中的美好特质都让我从 L 小姐身上体会了一遍,起初的那些爱慕感崇拜感变的浓度更高之外叠加了一种很强烈的依恋感,说实话当时我是意识到不对的:

和双相建立关系绝不能把自己变成“抑制剂”这种工具角色,也不能代入医生角色,也不能代替 Ta 的原生家庭成员

但是这段感情对我来说实在是“太爽了”,她本来就拥有疾病发生同时正常工作学习的能力,和我在一起后状态也在慢慢好转,所以我的预想都是偏正面的,带她见了我的很多亲人朋友,这其中不乏一些阅历很深很厉害、阅人无数的长辈,无一例外全部都对 L 小姐本人、我们的相处关系表示了极高的认可。我也和她的家人开始接触,这个过程中我感受到了强烈的价值观冲突,但是我觉得我也不和他们过日子而且也没想快速结婚,所以一直没觉得这是个大问题。

L 小姐和我这样甜蜜地爱了两年多,期间我能感知到一些关于家庭话题的回避,我出于尊重没有过问。其他方面的各种契合各种快乐就不提了,总之就是全部拉满。唯一就是我需要为她的情绪付出非常多精力,甚至改变了我的一些生活方式(对方会有要求:星星眼看着你问能不能多爱我一点这种)其实我当时已经意识到我真的沦为“血包”的角色了,但是看到对方越来越稳定,我和每个普信男一样,知道所有道理但是“她不一样、我们不一样”

直到今年,大约在去年最后一个多月的时候,我感觉到 L 小姐对我感情浓度下降了(体现在不再那么热衷了解关于我的东西,经常出现微信上各聊各的,我们长期异地,每天互发几百条消息,这是个重要时间点),但是见面时的相处、各种反应、亲密接触等等还是和往常一样。过年时对方家庭要求我提出结婚请求,双方父母见面洽谈,之前说过我和她的家庭接触不多但是感受到了强烈的价值观冲突,在这个洽谈过程中对方家庭的一些行为让我很生气,在后面和 L 小姐两人的沟通中爆发(我说了些很重的话),L 也一下变成了一种抑郁状态,表现出强烈的伤感(我怎么能这么讲话、我和家人在两边撕裂她、和她聊结婚事项不像情侣、以前也有过不照顾她情绪等等)

这里我又要打断一下,双相患者有个非常显著的特征:缺少事实记忆,只有情绪记忆,甚至发作期只有“情绪性推理”而不是“逻辑性推理”,并且他们会对自己通过感觉、直觉的判断深信不疑,以此为依据做重大决策,然后通过挑刺之类的方式强化自己的决策依据比如她说我以前有过言语打压、甚至矮化她,但是我问具体什么事件,她会说:我想不起来,我只记得当时的感觉(他们会相信既然我确实有这个情绪,那你一定做了什么过分的事)

这次事件爆发后我们仍在约会,约会内容、状态也和往常没感觉到什么不同,直到春节假期结束,她回到她现在工作的城市,向我用非常决绝的方式提出了分手。

我陷入了巨大的内耗中,因为我觉得是我造成的,尝试沟通无果,写了封道歉信,在寄信路上看到小区门口有对小情侣在打车的场景瞬间崩不住了,觉得是我一手毁掉了我的爱情。那天晚上我甚至出现了非常严重的躯体化反应:手抖、胸闷,回家的时候这种反应到了一种极点:看东西全部变成了扭曲的状态。这种状态一下让我清醒了,然后我的理智回来了一点,察觉到了一个之前忽略的点:L 和我两人在一起时都是比较稳定的状态(包括约会、旅游、短暂同居时),而每次出现情绪崩溃(或严重抑郁期)几乎都是她和家庭有连接时发生,但是稳定时期的她对家人又有非常强烈的依恋、信任。我觉得影响她的状态因素上,家庭是要大于我的(以前有过为了我和家里大吵),甚至这个疾病除了本身的生理缺陷,很可能就是原生家庭造成的。但是因为接触的不多没有足够信息,我又担心这个结论是我为了推卸责任的自动归因。

这样扛了两天实在受不了,找 L 小姐通了一通很长的电话,把所有的疑惑全部问了个清楚,最终真正的分手原因是:
她感觉自己病快好全了,对新生活有憧憬,我这个旧日里的情绪血包不再有强烈的爱情上的吸引力,这种感觉起始于上面那个我察觉情感浓度下降的时候,本来只是觉得结婚后的生活她不会喜欢,和我吵完架后突然想起来其实分手就可以

我意识到,她这次不是抑郁期,而是躁狂期(对直觉深信不疑且作为决策依据,表现出反常的无视道德约束)

我不知道大家看到这里是什么感觉,我自己当时的感觉其实只有“荒诞恐怖”而已,我自觉挺了解双相患者的一些行为,我知道现在这个“你和我的新生活不兼容”的结论是她当下脑子里的“真相”,过去的那些爱慕也是当时她脑子里的“真相”,就有一种我的爱情居然毁于一个冷笑话、我的爱情建立在器质性疾病上的荒诞感,和“我真的了解这个人的病情吗”的后怕。

那通电话我追问了许多细节,除了她的家庭原因推测没提(我能确认这个话题会变成刺激而且过去一直回避),她在亢奋的状态中笑着聊了关于未来“痊愈”的一些憧憬,所有她脑子里的“真相”和我的猜测全部吻合起来了。唯一失误的点是她自己觉得在整个 3 年里从未有过超过 1 个月的、比较长的“平静期”(线下见面即时性的状态判断我都是准确的)

而在过去,我从未察觉到她有现在这种剧烈的躁狂期,只在旅游中出现过几次“轻躁狂症状”

很纠结很矛盾,在这种情况下,失恋的痛苦反而成了最微不足道的(甚至我觉得这真的能称之为恋爱吗),我很担心这其实是一种病情的加重(大概率就是),而这种加重有一定可能是因为我“做的不够好”导致的;又觉得自己被当成“情绪血包”用了 3 年很可笑,过去那些真实感受到的美好我都不知道该定性成“表演”还是真实。

以上就是我经历的这段“爱情”史,下面列几个可能需要补充的点:

  1. 非严重躁狂期,具有较强的道德感和社会责任感
  2. 完全具有正常生活、工作的能力(外人根本看不出来)
  3. 会出现用草率的直觉做重大的人生决策(退学、跳槽这类)
  4. 往往会抗拒吃药,不信任医生、咨询师
  5. 如有原生家庭影响,一般会出现多个成员都有精神方面的疾病

千言万语汇成一句话:大伙如果遇到尽量别谈双相,实在要谈千万不要去当“情绪抑制剂”,不光是燃烧自己而且治标不治本,用课题分离思想去对待这段关系。

最近 OpenClaw 火的有点过于夸张了,楼主这边跟风体验,简单说说自己的认识。



0.很多人宣传的是飞书里一句话,AI 就可以帮你搞定一切?这个执行手段确实很新颖,但是正如站内有些朋友说的,很多时候你连远程开 claudeCode 也能实现类似的效果。个人认为这种更亲切的执行方式主要会更受大众喜爱,更加的“接地气”



1.这个产品的安全性是很低的,存在提示词注入等风险,所以大伙一般都是把它安装在云电脑或者 Mac mini 这种独立的沙盒里面让他随意发挥



2.由于 1 中的问题,这个产品本质上是个外包员工,这辈子也只能当个外包员工。因为部署在独立的新电脑上,系统是空荡荡的,他没法见到开发机的数据环境这些。至少对于我这种使用场景来说,它能够做到的独特的事不算很多。



3.和第一点中提到的接地气相矛盾的是,OpenClaw 部署流程并不算简单,尤其是 skills 各种定制,甚至还有了了小黄鱼上门安装 OpenClaw 这种一条龙业务。



4.真的有点烧 token ,恰逢各大国内云厂商纷纷在这个时间节点推出了自己的 coding plan ,站内也有很多广告,也不知道是巧合还是有别的意思。

大家好,我是 Redactly 的开发者,做这款 App 的初衷是发现日常分享截图时,很容易无意间泄露手机号、邮箱、住址、人脸这些敏感信息,找了一圈没找到用着顺手的打码工具,就自己开发了这款基于苹果端侧 AI 的智能打码 App ,现在上线了,来 V2EX 和大家分享,也准备了 20 个 Redactly Pro 年度版兑换码送给社区的朋友,具体规则在文末~

核心功能:苹果端侧 AI ,一键识别敏感信息自动打码

这款 App 全程基于 Apple on-device AI 处理,所有图片都不会离开你的设备,不用联网、不用注册账号,主打一个隐私安全。能自动检测并分类打码的内容包括:手机号、邮箱、URL 、人脸、家庭住址、姓名,每个类别都做了颜色标注,能一键开关整类打码,也能单独勾选 / 取消单个内容,精细调整超方便。
多种打码样式,基础版就够用,Pro 版更专业
基础免费版:高斯模糊(强度可调)、经典像素化(块大小可配)、纯色涂黑,日常分享的基础打码需求都能满足,还支持移除照片 EXIF 元数据,删掉隐藏的定位信息。
Pro 版专属:图案填充、表情印章、渐变模糊等 6 + 专业打码样式,还有无限制每日处理、批量打码(最多 50 张)、完整编辑历史、自定义打码预设,适合需要频繁处理截图的朋友。
关于隐私与适配
✅ 100% 端侧处理,无数据收集、无跟踪,照片永不传云端✅ 支持 iOS 18.3+、iPadOS 18.3+、macOS 15.3+( M1 及以上芯片)✅ 支持 22 种语言,包含简繁中文,全界面本地化✅ 体积仅 11.9MB ,轻量化不占内存
Pro 版订阅价格 & 兑换码福利
官方订阅价是周卡$0.99/年卡$2.99 ,这次直接送 20 个年度 Pro 版兑换码,先到先得~

下载地址:
https://apps.apple.com/cn/app/redactly-redact-blur/id6759426869

P9AJX6WYAMJN
LTRT6H9LHJYA
9KJE7PRXT6XH
MTW9R94T6L3W
4LT93FYHK6WT
EXNL6XPLFT4W
MFEF9EWRYRLY
N4M67PPMF9ET
L7NAT4W96AFJ
4A6TWYE366EM
J76FWJPJ4XY3
YR9P77F93AHN
AAMTLMYWP3A9
M73EF4HJNWW3
WKRL94JLA67E
WKYX7KA6F793
4MLY6H4X3YMR
4NNNJ6TL97T7
EXNLEKX44TKM
HREJPYPEAPEF

简介:1联合体类型的声明;2联合体的特点;3联合体大小的计算;4枚举类型的声明;5枚举类型的优点;6枚举类型的使用

1 联合体

1.1 联合体类型的声明

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以是不同的类型。

但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体

给联合体其中一个成员赋值,其他成员的值也跟着变化。

使用联合体的目的是为了节省空间。联合体成员在同一时间只能使用一个。

#include <stdio.h>
//联合类型的声明
union Un
{
    char c;
    int i;
};

int main()
{
    //联合变量的定义
    union Un un = { 0 };
    //计算连个变量的大小
    printf("%zd\n", sizeof(un));
    return 0;
}

1.2 联合体的大小

  • 联合的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include <stdio.h>
union Un1
{
    char c[5];
    int i;
};
union Un2
{
    short c[7];
    int i;
};
int main()
{
    //下面输出的结果是什么?
    printf("%zd\n", sizeof(union Un1));
    printf("%zd\n", sizeof(union Un2));
    return 0;
}

1.3 联合体判断大小端

联合体的特点是所有成员共用同一块内存空间,这个特点用来判断大小端很合适。

//使用联合体判断大小端
#include <stdio.h>
int cheak_sys()
{
    union
    {
        char c;
        int i;
    }n;
    n.i = 1;
    return n.c;
}

int main()
{
    if (cheak_sys())
        printf("小端\n");
    else
        printf("大端\n");
    return 0;
}

2 枚举类型

2.1 枚举类型的声明

枚举顾名思义就是一一列举。

把可能的取值一一列举。

比如我们现实生活中:

一周的星期一到星期日是有限的7天,可以一一列举

性别有:男、女、保密,也可以一一列举

月份有12个月,也可以一一列举

三原色,也可以列举

这些数据的表示就可以使用枚举了。

enum Color//颜色
{
    RED,
    GREEN,
    BLUE
}

上面定义的enum Color就是枚举类型。

{}中的内容是枚举类型的可能取值,也叫枚举常量

这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

下面是一个赋初值的问题:

枚举默认从0开始,所以X1是0,故Y1是1,给了数字后会根据数字向后推,那么Z1是255,A1是256,所以B1是257。

2.2 枚举类型的优点

我们也可以使用#define定义常量,为什么非要使用枚举?

枚举的优点:

  1. 增加代码的可读性和可维护性
  2. #define定义的标识符比较枚举有类型检查,更加严谨。
  3. 便于调试,预处理阶段会删除#define定义的符号
  4. 使用方便,一次可以定义多个常量
  5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

有关#define

说明:结构体向最长的char对齐,前两个位段元素一共4+2位,不足8位,合起来占1字节,最后一个单独1字节,一共3字节。另外,#define执行的是查找替换, sizeof(struct _Record_Struct) MAX_SIZE这个语句其实是32+3,结果为9。

2.3 枚举类型的使用

enum Color//颜色
{ 
    RED=1;
    GREEN=2;
    BLUE=4;
};

enum Color clr = GREEN;//使用枚举常量给枚举变量赋值

那是否可以拿整数给枚举变量赋值呢?在C语言中是可以的,但是在C++是不行的,C++的类型检查比

较严格。

简洁:1结构体类型的声明;2结构体变量的创建和初始化;3结构成员访问操作符;4结构体内存对齐;5结构体传参;6结构体实现位段

1 结构体类型的声明

1.1 回顾

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

struct tag
{ 
    member-list;
}variable-list;

结构的声明、结构体变量的创建和初始化,例如:

#include <stdio.h>
struct Stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
};
int main()
{
    //按照结构体成员的顺序初始化
    struct Stu s = { "张三", 20, "男", "20230818001" };
    printf("name: %s\n", s.name);
    printf("age : %d\n", s.age);
    printf("sex : %s\n", s.sex);
    printf("id  : %s\n",s.id);

    //按照指定的顺序初始化
    struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex = "女" };
    printf("name: %s\n", s2.name);
    printf("age : %d\n", s2.age);
    printf("sex : %s\n", s2.sex);
    printf("id  : %s\n", s2.id);
    return 0;
}

1.2 结构的特殊声明

在声明结构的时候,可以不完全的声明。

比如:

//匿名结构体类型
struct
{
    int a;
    char b;
    float c;
}x;

struct
{
    int a;
    char b;
    float c;
}a[20], *p;

上面的两个结构在声明的时候省略掉了结构体标签(tag)。

问题:p = &x是否合法?

编译器会把上面的两个声明当成完全不同的两个类型,所以是非法的。

匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使用一次。

注意:匿名结构体类型并不推荐使用,可能会有各种问题

1.3 结构的自引用

struct Node
{
    int data;
    struct Node* next;
};

在一个结构体中包含了一个同类型结构体的指针,形成链式结构。

问题:在结构体自引用使用的过程中,夹杂了typedef对匿名结构体类型重命名,也容易引入问题,看看

下面的代码,可行吗?

typedef struct
{ 
    int data;
    Node* next;
}Node;

答案是不行的,因为Node是对前面的匿名结构体类型的重命名产生的,但是在匿名结构体内部提前使

用Node类型来创建成员变量,这是不行的。

解决方案如下:定义结构体不要使用匿名结构体了

typedef struct Node
{ 
    int data;
    struct Node* next;
}Node;

2 结构体内存对齐(重点)

我们已经掌握了结构体的基本使用了。现在我们深入讨论一个问题:计算结构体的大小。

这也是一个特别热门的考点:结构体内存对齐

2.1 对齐规则

结构体对齐遵循的规则如下:

  1. 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数 = 编译器默认的一个对齐数与该成员变量大小的 较小值。

VS中默认的值为8

Linux中gcc没有默认对齐数,对齐数就是成员自身的大小

  1. 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍。
  2. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。
//练习1 
struct S1
{
    char c1;
    int i;
    char c2;
};
//练习2
struct S2
{
    char c1;
    char c2;
    int i;
};
//练习3
struct S3
{
    double d;
    char c;
    int i;
};
//练习4-结构体嵌套问题
struct S4
{
    char c1;
    struct S3 s3;
    double d;
};

int main()
{
    printf("%zd\n", sizeof(struct S1));
    printf("%zd\n", sizeof(struct S2));
    printf("%zd\n", sizeof(struct S3));
    printf("%zd\n", sizeof(struct S4));
    return 0;
}

2.2 为什么存在内存对齐?

  1. 平台原因(移植原因):

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

  1. 性能原因:

数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。假设一个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用一个内存操作来读或者写值了。否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。

总体来说:结构体的内存对齐是拿空间来换取时间的做法。

那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:

让占用空间小的成员尽量集中在一起
//例如: 
struct S1
{ 
    char cl;
    int i;
    char c2;
};

struct S2
{
    char cl;
    char c2;
    int i;
};

2.3 修改默认对齐数

#pragma这个预处理指令,可以改变编译器的默认对齐数。

#pragma pack(l)//设置默认对齐数为:1
#pragma pack()//取消设置的对齐数,还原为默认

3 结构体传参

结论:结构体传参的时候,建议传结构体的地址。

原因:

函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。

如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

struct S
{
    int data[1000];
    int num;
};
struct S s = { { 1, 2, 3, 4 }, 1000 };

//结构体传参
void print1(struct S s)
{
    printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
    printf("%d\n", ps->num);
}

int main()
{
    print1(s); //传结构体
    print2(&s); //传地址,用这种
    return 0;
}

4 结构体实现位段

4.1 什么是位段

位段的声明和结构是类似的,有两个不同:

  1. 位段的成员必须是int、unsigned int、signed intchar,在C99中位段成员的类型也可以选择其他类型。
  2. 位段的成员名后边有一个冒号和一个数字。

位段中的位是二进制位。

比如:

struct A 
{ 
    int _a:2;
    int _b:5;
    int _c:10;
    int _d:30;
};

A就是一个位段类型。

位段的应用举例:网络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要几个bit位就能描述,这里使用位段,能够实现想要的效果,也节省了空间,这样网络传输的数据报大小也会较小一些,对网络的畅通是有帮助的。

4.2 位段的内存分配

  1. 位段的成员可以是int unsigned int signed int或者是char等类型
  2. 位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的。
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

4.3 位段的跨平台问题

  1. int位段被当成有符号数还是无符号数是不确定的。
  2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配,标准尚未定义。
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结:

跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

如果使用位段,一般会根据不同的环境写不同的代码。

4.4 位段使用的注意事项

位段的几个成员共有同一个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的。内存中每个字节分配一个地址,一个字节内部的bit位是没有地址的。

所以不能对位段的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在一个变量中,然后赋值给位段的成员。 就如4.2中的赋值过程。

最近看到全民都在 All in OpenClaw ,X 鱼上各种上门安装,腾讯深圳甚至直接摆摊免费安装,各大平台都在大力鼓吹,真的有那么多的需求吗?这场狂热是不是一场噱头?
欢迎交流,发表你的看法!

OpenClaw 没改名前就深入研究过,算是小有经验吧,做过各种 Skill ,也帮一些公司定制过 bot 和自动化业务流程,没想到这东西现在这么火,有很多不是很懂技术的人感兴趣也想安装,或者是有各种疑难杂症需要解决,通过朋友以及各种渠道找到我,我就帮着处理一下,能远程的就远程处理,如果人家需要上门我就跑一趟,收个辛苦费,截止到今天,算了一下 3 月到今天一共收入是 4100 块钱,谈谈体会。

很多人完全就是凑热闹,最有印象是一个江西的老哥,连夜开车过来找我,见面后我发现他带着台 M4max 芯片 48G 内存的 MacBookPro ,看我一通操作后问了我一个问题,“为什么你打入几个数字后会出现一个网站”,我愣了 10 秒钟不知道怎么回复他。

也碰到过白嫖怪,有一个小公司的高管让我过去帮他安装,到了公司后我帮他安装好了,他说还不够,光安装他也会,他要我帮他实现各种功能,不然不给钱,说着他把手机掏出来,上面有个清单,里面列着:整理桌面、整理邮件、运营小红书……大概 10 个需求,要我全部帮他实现,不然不给钱,我说不带这样的,他说那你走吧。

还碰到过一个大哥,看起来应该是基金公司的,问我能不能回答几个问题,他自己捣鼓碰到点障碍,我说可以的,他直接先赚了 300 块红包过来,然后说他的问题,我帮他一一解决,虽然花了点时间但还是蛮开心的,尊重技术人员,原以为知识付费,我也很尊重这种客户。