当前位置: 首页 > news >正文

前端 TypeError 错误永久消失术

作者:来自 vivo 互联网大前端团队- Sun Maobin

通过开发 Babel 插件,打包时自动为代码添加 可选链运算符(?.),从而有效避免 TypeError 的发生。

一、背景介绍

在 JS 中当获取引用对象为空值的属性时,程序会立即终止运行并报错:TypeError: Cannot read properties of …

在 ECMAScript 2020 新增的 可选链运算符(?.),当属性值不存在时返回 undefined,从而可有效避免该错误的发生。

let a
a.b.c.d // Uncaught TypeError: Cannot read properties of undefined (reading 'b')
a?.b?.c?.d // undefined

本文将分享如何借助这一特性开发 Babel 插件,自动为代码添加 ?.,从而根治系统中的 TypeError 错误。

二、项目痛点

  1. 维护中的代码可能存在 TypeError 隐患,数量大维护成本高,比如:存在大量直接取值操作:a.b.c.d

  2. 在新代码中使用 ?. 书写起来太繁琐,同时也导致源码不易阅读,比如:a?.b?.c?.d

因此,如果我们只要在打包环节自动为代码添加 ?.,就可以很好解决这些问题。

三、解决思路

开发 Babel 插件 在打包时进行代码转换:

  • 将存在隐患的操作符 .[] 转换为 ?.

  • 将臃肿的短路表达式 && 转换为 ?.

// in
a.b.c.d
a['b']['c']['d']
a && a.b && a.b.c && a.b.c.d// out
a?.b?.c?.d

四、目标价值

通用于任何基于 Babel 的 JS 项目,在源码 0 改动的情况下,彻底消灭 TypeError 错误。

五、功能实现

5.1 Babel 插件核心

  • 识别代码中可能存在 TypeError 的风险操作:属性获取方法调用

  • 支持自定义 Babel 参数配置,includesexcludes 代码转换规则

  • 短路表达式 && 自动优化

import { declare } from '@babel/helper-plugin-utils';
import * as t from '@babel/types';export default declare((api, options) => {// 仅支持 Babel7 api.assertVersion(7);return {// Babel 插件名称name: 'babel-plugin-auto-optional-chaining',visitor: {/*** 通过 Babel AST 解析语法后,仅针对以下数据类型做处理* - MemberExpression:a.b 或 a['b']* - CallExpression:a.b() 或 a['b']()* - OptionalMemberExpression:a?.b 或 a?.['b']* - OptionalCallExpression:a.b?.() 或 a.['b']?.()*/'MemberExpression|CallExpression|OptionalMemberExpression|OptionalCallExpression'(path) {// 避免重复处理if (path.node.extra.hasAoc) return;// isValidPath:通过 Babel 配置参数决定是否处理该节点const isMeCe = path.isMemberExpression() || path.isCallExpression();if (isMeCe && !isValidPath(path, options)) return;// 属性获取// shortCircuitOptimized:&& 短路表达式优化后再做替换处理if (path.isMemberExpression() || path.isOptionalMemberExpression()) {const ome = t.OptionalMemberExpression(path.node.object, path.node.property, path.node.computed, true);if (!shortCircuitOptimized(path, ome)) {path.replaceWith(ome);};};// 方法掉用// shortCircuitOptimized:&& 短路表达式优化后再做替换处理if (path.isCallExpression() || path.isOptionalCallExpression()) {const oce = t.OptionalCallExpression(path.node.callee, path.node.arguments, false);if (!shortCircuitOptimized(path, oce)) {path.replaceWith(oce);};};// 添加已处理标记path.node.extra.hasAoc = true;}}};
});

5.2 Babel 参数配置

支持 includesexcludes 两个参数,决定自动处理的代码 ?. 的策略。

  • includes - 仅处理指定代码片段

  • excludes - 排除指定代码片段不做处理

// includes 列表,支持正则
const isIncludePath = (path, includes: []) => {return includes.some(item => {let op = path.hub.file.code.substring(path.node.start, path.node.end);return new RegExp(`^${item}$`).test(op);})
};// excludes 列表,支持正则
const isExcludePath = (path, excludes: []) => {// 忽略:excludes 列表,支持正则return excludes.some(item => {let op = path.hub.file.code.substring(path.node.start, path.node.end);return new RegExp(`^${item}$`).test(op);})
};// 校验配置参数
const isValidPath = (path, {includes, excludes}) => {// 如果配置了 includes,仅处理 includes 匹配的节点if (includes?.length) {return isIncludePath(path, includes);}// 如果配置了 excludes,则不处理 excludes 匹配的节点if (includes?.length) {return !isExcludePath(path, includes);}// 默认全部处理return true;
}

5.3 短路表达式优化

支持添加参数 optimizer=false 关闭优化

const shortCircuitOptimized = (path, replaceNode) => {// 支持添加参数 optimizer=false 关闭优化if (options.optimizer === false) return false;const pc = path.container;// 判断是否逻辑操作 && if (pc.type !== 'LogicalExpression') return false;// 只处理 a && a.b 中的 a.bif (pc.type === 'LogicalExpression' && path.key === 'left') return false;// 递归寻找上一级是否逻辑表达式,即:a && a.b && a.b.cconst pp = path.parentPath;if (pp.isLogicalExpression() && path.parent.operator === '&&'){let ln = pp.node.left;let rn = pp.node.right?.object ?? pp.node.right?.callee ?? {};const isTypeId = type => 'Identifier' === type;const isValidType = type => ['MemberExpression','OptionalMemberExpression','CallExpression','OptionalCallExpression'].includes(type);const isEqName = (a, b) => {if ((a?.name ?? b?.name) === undefined) return false;return a?.name === b?.name;};// 递归处理并替换// 如:a && a.b && a.b.c ==> a?.b && a.b.c ==> a?.b?.cconst getObj = (n, r = '') => {const reObj = obj => {r = r ? `${obj.name}.${r}` : obj.name;};isTypeId(n.property?.type) && reObj(n.property);isTypeId(n.object?.type) && reObj(n.object);isTypeId(n.callee?.type) && reObj(n.callee);if (isValidType(n.object?.type)) {return getObj(n.object, r);};if (isValidType(n.callee?.type)) {return getObj(n.callee, r);};return r;};// eg:a && a.bif (isTypeId(ln.type) && isTypeId(rn.type)) {if (isEqName(ln, rn)) {return pp.replaceWith(replaceNode);}};// eg:a && a.b | a && a.b.c...if (isTypeId(ln.type) && isValidType(rn.type)) {const rnObj = getObj(rn);if (rnObj.startsWith(ln.name)) {return pp.replaceWith(replaceNode);}};// eg:a.b && a.b.c | a.b && a.b.c...// 注意:a.b.c && a.b.d 不会被转换if (isValidType(ln.type) && isValidType(rn.type)) {const lnObj = getObj(ln);const rnObj = getObj(rn);if (rnObj.startsWith(lnObj)) {return pp.replaceWith(replaceNode);}};};return false;
};

六、插件应用

配置 babel.config.js 文件。

支持3个配置项:

  • includes - 仅处理指定代码片段(优先级高于 excludes

  • excludes - 排除指定代码片段不做处理

  • optimizer - 如果设置为 false 则关闭优化短路表达式 &&

module.exports = {plugins: [['babel-plugin-auto-optional-chaining', {excludes: ['new .*',       // eg:new a.b() 不能转为 new a.b?.()'process.env.*' // 固定短语通过.链接,不做处理],// includes: [],// optimizer: false}]]
}

七、不足之处

自动为代码添加 ?. 可能会导致打包后文件体积略微增加,从而影响页面访问速度。

八、相关插件

对于不支持 可选链运算符 (?.) 的浏览器或者版本(如:Chrome<80),可以再使用插件 @babel/plugin-transform-optional-chaining 做反向降级。

使用后效果如下:

// 第1步:考虑健壮性,使用本文插件将代码自动转为可选链
a.b ===> a?.b// 第2步:考虑兼容性,使用 @babel/plugin-transform-optional-chaining 再做反向降级
a?.b ==> a === null || a === void 0 ? void 0 : a.b;

九、插件测试

以下是一些测试用例仅供参考,使用 babel-plugin-tester 进行测试。

Input 输入用例

// 常规操作
const x = a.b.c.d
const y = a['b']['c'].d
const z = a.b[c.d].e
if(a.b.c.d){}
switch (a.b.c.d){}// 特殊操作
(a).b // 括号运算
const w = +a.b.c // 一元运算// 方法调用
a.b.c.d()
a().b
a.b().c
a.b(c.d).e
fn(a.b.c.d)
fn(a.b, 1)
fn(...a)
fn.a(...b).c(...d)// 短路表达式优化
// optional member
a && a.b
a && a.b && a.b.c
a.b && a.b.c && a.b.c.d
this.a && this.a.b
this.a.b && this.a.b.c && this.a.b.c.d
this['a'] && this['a'].b
this['a'] && this['a']['b'] && this['a']['b']['c']
this['a'] && this['a'].b && this['a'].b['c']// optional method
a && a.b()
a && a.b().c
a.b && a.b.c()
a && a.b && a.b.c()// assign expression
let a = a && a.b
let b = a && a.b && a.b.c && a.b.c.d
let c = a && a.b && a.b.c()// self is optional chaining
a && a?.b
a && a.b && a?.b?.c
a && a?.b && a?.b?.c
a && a?.b() && a?.b()?.c// function args
fn(a && a.b)
fn(a && a.b && a.b.c)// only did option chaining
a.b && b.c
a.b && a.c.d
a.b && a.b.c && a.c.d
a.b.c && a.b.d
a.b.c && a.b
a.b.c.d && a.b.c.e// not handle
a && b
a && b && c
a || b
a || b || true// 忽略赋值操作
x.a = 1
x.a.c = 2// 忽略算术运算
a.b++
++a.b
a.b--
--a.b// 忽略指派赋值运算
a.b += 1
a.b -= 1// 忽略 in/of
for (a in b.c.d);
for (bar of b.c.d);// 忽略 new 操作符
new a.b()
new a.b.c()
new a.b.c.d()
new a().b
new a.b().c.d// 配置忽略项
process.env.a
process.env.a.b.c// 忽略 ?. 本身
a?.b
a?.b?.c?.d

Out 结果输出:

// 常规操作
const x = a?.b?.c?.d;
const y = a?.["b"]?.["c"]?.d;
const z = a?.b?.[c?.d]?.e;
if (a?.b?.c?.d) {
}
switch (a?.b?.c?.d) {
}// 特殊操作
a?.b; // 括号运算
const w = +a?.b?.c; // 一元运算// 方法调用
a?.b?.c?.d();
a()?.b;
a?.b()?.c;
a?.b(c?.d)?.e;
fn(a?.b?.c?.d);
fn(a?.b, 1);
fn(...a);
fn?.a(...b)?.c(...d);// 短路表达式优化
// optional member
a?.b;
a?.b?.c;
a?.b?.c?.d;
this.a?.b;
this.a?.b?.c?.d;
this["a"]?.b;
this["a"]?.["b"]?.["c"];
this["a"]?.b?.["c"];// optional method
a?.b();
a?.b()?.c;
a?.b?.c();
a?.b?.c();// assign expression
let a = a?.b;
let b = a?.b?.c?.d;
let c = a?.b?.c();// self is optional chaining
a?.b;
a?.b?.c;
a?.b?.c;
a?.b()?.c;// function args
fn(a?.b);
fn(a?.b?.c);// only did option chaining
a?.b && b?.c;
a?.b && a?.c?.d;
a?.b?.c && a?.c?.d;
a?.b?.c && a?.b?.d;
a?.b?.c && a?.b;
a?.b?.c?.d && a?.b?.c?.e;// not handle
a && b;
a && b && c;
a || b;
a || b || true;// 忽略赋值操作
x.a = 1;
x.a.c = 2;// 忽略算术运算
a.b++;
++a.b;
a.b--;
--a.b;// 忽略指派赋值运算
a.b += 1;
a.b -= 1;// 忽略 in/of
for (a in b.c.d);
for (bar of b.c.d);// 忽略 new 操作符
new a.b();
new a.b.c();
new a.b.c.d();
new a().b;
new a.b().c.d;// 配置忽略项
process.env.a;
process.env.a.b.c;// 忽略 ?. 本身
a?.b;
a?.b?.c?.d;

十、写在最后

本文通过介绍如何开发一个 Babel 插件,在打包时自动为代码添加 可选链运算符(?.),从而有效避免 JS 项目 TypeError 的发生。

希望这个思路能够有效的提升大家项目的健壮性和稳定性。

十一、参考资料

  • tc39/proposal-optional-chaining

  • 可选链运算符(?.)

  • Babel插件手册

  • Babel’s optional chaining AST spec

  • ESTree

  • eslint/no-unsafe-optional-chaining

相关文章:

前端 TypeError 错误永久消失术

作者&#xff1a;来自 vivo 互联网大前端团队- Sun Maobin 通过开发 Babel 插件&#xff0c;打包时自动为代码添加 可选链运算符(?.)&#xff0c;从而有效避免 TypeError 的发生。 一、背景介绍 在 JS 中当获取引用对象为空值的属性时&#xff0c;程序会立即终止运行并报错&…...

【视频总结】Deep Dive into LLMs like ChatGPT 深入探索像ChatGPT这样的大语言模型|Andrej Karpathy

【视频总结】Deep Dive into LLMs like ChatGPT 深入探索像ChatGPT这样的大语言模型&#xff5c;Andrej Karpathy 大型语言模型&#xff08;LLM&#xff09;工作原理与使用指南核心观点模型训练三阶段1. 预训练阶段2. 后训练阶段&#xff08;Post-training&#xff09;3. 强化学…...

内网ip网段记录

1.介绍 常见的内网IP段有&#xff1a; A类&#xff1a; 10.0.0.0/8 大型企业内部网络&#xff08;如 AWS、阿里云&#xff09; 10.0.0.0 - 10.255.255.255 B类&#xff1a;172.16.0.0/12 中型企业、学校 172.16.0.0 - 172.31.255.255 C类&#xff1a;192.168.0.0/16 家庭…...

本地部署DeepSeek + AnythingLLM 搭建高效安全的个人知识库

环境准备: 本地部署方案请参考博客:windows平台本地部署DeepSeek大模型+Open WebUI网页界面(可以离线使用)-CSDN博客 windows平台本地部署DeepSeek大模型+Chatbox界面(可以离线使用)-CSDN博客 根据本人电脑配置:windows11 + i9-13900HX+RTX4060+DDR5 5600 32G内存 确…...

Xcode证书密钥导入

证书干嘛用 渠道定期会给xcode证书&#xff0c;用来给ios打包用&#xff0c;证书里面有记录哪些设备可以打包进去。 怎么换证书 先更新密钥 在钥匙串访问中&#xff0c;选择系统。(选登录也行&#xff0c;反正两个都要导入就是了)。 mac中双击所有 .p12 后缀的密钥&#xff…...

机械学习基础-5.分类-数据建模与机械智能课程自留

data modeling and machine intelligence - CLASSIFICATION 为什么我们不将回归技术用于分类&#xff1f;贝叶斯分类器&#xff08;The Bayes Classifier&#xff09;逻辑回归&#xff08;Logistic Regression&#xff09;对逻辑回归的更多直观理解逻辑 /sigmoid 函数的导数我们…...

springcloud集成gateway

本篇文章只介绍gateway模块的搭建步骤&#xff0c;并无gateway详细介绍 gateway详解请查看&#xff1a;SpringCloudGateway官方文档详解 前置处理 父模块中已指定版本 不知道如何选择版本看这篇&#xff1a; 手把手教你梳理springcloud与springboot与springcloudalibaba的版本…...

RocketMQ之偏移量Offset

偏移量&#xff1a;偏移量是 ConsumerQueue 文件中的逻辑位置&#xff0c;表示消息在队列中的顺序。每次消费通过偏移量在索引文件ConsumerQueue中快速找到对应的消息内容。 1.Broker端 Broker端主要通过ConsumerManageProcessor类来处理Offset的更新查询的请求&#xff0c;真…...

2024-2025年主流的开源向量数据库推荐

以下是2024-2025年主流的开源向量数据库推荐&#xff0c;涵盖其核心功能和应用场景&#xff1a; 1. Milvus 特点&#xff1a;专为大规模向量搜索设计&#xff0c;支持万亿级向量数据集的毫秒级搜索&#xff0c;适用于图像搜索、聊天机器人、化学结构搜索等场景。采用无状态架…...

Redis 集群(Cluster)和基础的操作 部署实操篇

三主三从 集群概念 Redis 的哨兵模式&#xff0c;提高了系统的可用性&#xff0c;但是正在用来存储数据的还是 master 和 slave 节点&#xff0c;所有的数据都需要存储在单个 master 和 salve 节点中。 如果数据量很大&#xff0c;接近超出了 master / slave 所在机器的物理内…...

RTD2775QT/RTD2795QT瑞昱显示器芯片方案

RTD2775QT与RTD2795QT&#xff1a;高性能4K显示驱动芯片 RTD2775QT与RTD2795QT是瑞昱半导体公司推出的两款高性能显示驱动芯片&#xff0c;专为满足现代显示设备对高清、高分辨率的需求而设计。这两款芯片不仅支持4K分辨率&#xff0c;还具备丰富的功能和卓越的性能&#xff0…...

Java进阶面试题

Java 进阶面试问题列表翻译自Java developer interview questions: The hard part&#xff0c;从属于笔者的Java入门与工程实践系列。最近公司打算招几个 Java 开发人员&#xff0c;正巧在 Reddit 上看到了该文&#xff0c;顺手翻译了一波。只是单纯的问题列表&#xff0c;可能…...

Spring Cloud-Sentinel

Sentinel服务熔断与限流 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。 官网地址&#xff1a;home | Sentinelhttps://sen…...

21道关于Vue3的面试题及其解析

Vue 3是一种流行的JavaScript框架&#xff0c;它是Vue.js的第三个主要版本&#xff0c;于2020年9月18日正式发布。关于Vue 3的一些关键信息&#xff1a; 文章目录 1. 性能优化2. 组合式API&#xff08;Composition API&#xff09;3. 响应式系统改进4. 更好的TypeScript支持5. …...

使用 Visual Studio Code (VS Code) 开发 Python 图形界面程序

安装Python、VS Code Documentation for Visual Studio Code Python Releases for Windows | Python.org 更新pip >python.exe -m pip install --upgrade pip Requirement already satisfied: pip in c:\users\xxx\appdata\local\programs\python\python312\lib\site-pa…...

深入理解 MyBatis 框架的核心对象:SqlSession

Mybatis框架中的SqlSession对象详解 引言 MyBatis 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息&#xff0…...

day09_实时类标签/指标

文章目录 day09_实时类标签/指标一、日志数据实时采集2、Flume简介2.3 项目日志数据采集Flume配置2.3.1 涉及的Flume组件和参数2.3.2 Nginx日志采集2.3.3 用户行为日志采集 二、Nginx日志数据统计1、日志格式说明2、数据ETL2.1 日志抽取2.1.1 正则表达式2.1.2 基于Spark实现Ngi…...

AWTK-WEB 快速入门(4) - JS Http 应用程序

XMLHttpRequest 改变了 Web 应用程序与服务器交换数据的方式&#xff0c;fetch 是 XMLHttpRequest 继任者&#xff0c;具有更简洁的语法和更好的 Promise 集成。本文介绍一下如何使用 JS 语言开发 AWTK-WEB 应用程序&#xff0c;并用 fetch 访问远程数据。 用 AWTK Designer 新…...

github不翻墙就可以访问

目录 简介资料准备windows平台设置下载运行git设置firefox设置 ubuntu平台设置下载启动服务设置系统代理git设置firefox设置证书 注意事项 简介 由于github访问不稳定,严重影响了国内软件开发,在网上搜索并验证了一些方法.现在整理出来一个可以正常使用的方法, 在windows和Lin…...

【AI-32】浅显易懂地说一下LangChain

好的&#xff01;我来用最通俗的方式解释一下 LangChain 是什么&#xff0c;以及它为什么在 AI 开发中如此重要。 一句话理解 LangChain LangChain 是一个帮你快速搭建AI应用的工具箱&#xff0c;它把大型语言模型&#xff08;如 GPT&#xff09;和外部数据、计算工具、业务流…...

使用 Nginx 搭建代理服务器(正向代理 HTTPS 网站)指南

在网络应用中&#xff0c;代理服务器是用于中转用户请求和服务端响应的工具。正向代理主要用于客户端与外部服务器之间的访问代理&#xff0c;帮助客户端隐藏其 IP 地址或访问受限资源。本文将详细介绍如何使用 Nginx 搭建正向代理服务器&#xff0c;特别是针对 HTTPS 网站的代…...

Linux学习笔记之进程

进程 进程的定义 进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配的基本单位&#xff0c;也是操作系统结构的基础。   例如当QQ程序运行的时候&#xff0c;计算机会先从磁盘读取QQ程序到内存&#xff0c;然后OS管理这个程序&#xff0c;…...

win11 终端乱码导致IDE 各种输出也乱码

因为 win11 终端乱码导致IDE 各种输出也乱码导致作者对此十分头大。所以研究了各种方法。 单独设置终端编码对 HKEY_CURRENT_USER\Console 注册表进行修改对 HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processo 注册表进行修改使用命令[Console]::OutputEncoding [Syst…...

iOS主要知识点梳理回顾-5-运行时方法交换

方法交换可以放在 load 或 initialize 方法中&#xff0c;也可以自己根据时机来空&#xff0c;比如开启某个开关后才需要交换方法。如果是在load中调用&#xff0c;交换工作会在类加载时&#xff08;程序启动&#xff09;自动调用&#xff1b;如果是在initialize中调用&#xf…...

python后端调用Deep Seek API

python后端调用Deep Seek API 需要依次下载 ●Ollama ●Deepseek R1 LLM模型 ●嵌入模型nomic-embed-text / bge-m3 ●AnythingLLM 参考教程&#xff1a; Deepseek R1打造本地化RAG知识库:安装部署使用详细教程 手把手教你&#xff1a;deepseek R1基于 AnythingLLM API 调用本地…...

Unity开发播放视频

Unity开发播放视频 介绍VideoPlayer原理步骤VideoPlayer动态加载 总结 介绍 原生Unity播放视频VideoPlayer播放视频&#xff0c;这里我没有选择使用插件&#xff0c;还有一个播放视频的插件也可以AVPro Video&#xff0c;这里不过多介绍就说一下原生VideoPlayer的基础用法。 …...

【练习】图论

F. Friendly Group 图中选择一个点-1 边两端点都选择1 边一个端点选择-1 添加链接描述 #include<iostream> using namespace std; #include<vector> #include<cstring> const int N300010; int n,m; vector<int> G[N]; int temp1,temp2; bool vis[N…...

gis风场加载

https://gitee.com/openGPL json数据格式使用v1 “sakitam-gis/mapbox-wind”: “1.1.2” import { WindLayer } from "sakitam-gis/mapbox-wind"; windLayer new WindLayer("wind", res.data, {windOptions: {// colorScale: (m) > {// // consol…...

大疆无人机需要的kml文件如何制作kml导出(大疆KML文件)

大疆无人机需要的轨迹kml文件&#xff0c;是一种专门的格式&#xff0c;这个kml里面只有轨迹点&#xff0c;其它的属性信息都不需要。 BigemapPro提供了专门的大疆格式输出&#xff0c; 软件这里下载 www.bigemap.com 安装后&#xff0c;kml导入如下图&#xff1a; 然后选择…...

【CXX】2 CXX blobstore客户端说明

本示例演示了一个调用blobstore服务的C客户端的Rust应用程序。事实上&#xff0c;我们会看到两个方向的调用&#xff1a;Rust到C以及C到Rust。对于您自己的用例&#xff0c;您可能只需要其中一个方向。 示例中涉及的所有代码都显示在此页面上&#xff0c;但它也以可运行的形式提…...

图数据库neo4j进阶(一):csv文件导入节点及关系

CSV 一、load csv二、neo4j-admin import<一>、导入入口<二>、文件准备<三>、命令详解 一、load csv 在neo4j Browser中使用Cypher语句LOAD CSV,对于数据量比较大的情况,建议先运行create constraint语句来生成约束 create constraint for (s:Student) req…...

3.3 学习UVM中的uvm_driver 类分为几步?

文章目录 前言1. 定义2. 核心功能3. 适用场景4. 使用方法5. 完整代码示例5.1 事务类定义5.2 Driver 类定义5.3 Sequencer 类定义5.4 测试平台 6. 代码说明7. 总结 前言 以下是关于 UVM 中 uvm_driver 的详细解释、核心功能、适用场景、使用方法以及一个完整的代码示例&#xff…...

Docker 常用命令基础详解(一)

一、Docker 初相识 在当今数字化时代&#xff0c;软件开发和部署的效率与灵活性成为了关键因素。Docker&#xff0c;作为一款开源的应用容器引擎&#xff0c;犹如一颗璀璨的明星&#xff0c;照亮了软件开发与部署的道路&#xff0c;为开发者们带来了前所未有的便利。它就像是一…...

机器学习之AAE(Adversarial Autoencoder,对抗自编码器)生成数据样本

对抗自编码器(Adversarial Autoencoder,AAE)是一种结合了自编码器(Autoencoder)和生成对抗网络(GAN)的方法,用于生成新数据样本。它的目标是学习到数据的潜在分布,并通过生成对抗训练来优化潜在空间,使其接近一个已知的简单分布(例如,高斯分布)。 AAE的结构和训练…...

用大模型学大模型03-数学基础 概率论 最大似然估计(MLE)最大后验估计(MAP)

https://metaso.cn/s/r4kq4Ni 什么是最大似然估计&#xff08;MLE&#xff09;最大后验估计&#xff08;MAP&#xff09;&#xff1f;深度学习中如何应用&#xff0c;举例说明。 好的&#xff0c;我现在需要回答关于最大似然估计&#xff08;MLE&#xff09;和最大后验估计&…...

名词解释:npm,cnpm,yarn,vite,vue,electron

1. npm (Node Package Manager) 读音: “N-P-M” 或者直接读作 “npm”。 npm 是 Node.js 的官方包管理器&#xff0c;用于安装、发布和管理 JavaScript 软件包。它允许开发者轻松地共享代码&#xff0c;并且可以通过命令行工具来管理依赖关系。通过 npm init 命令可以交互式…...

ESXi安装【真机和虚拟机】(超详细)

项目简介&#xff1a; ESXi&#xff08;Elastic Sky X Integrated&#xff09;是VMware公司开发的一种裸机虚拟化管理程序&#xff0c;允许用户在单一物理服务器上运行多个虚拟机&#xff08;VM&#xff09;。它直接安装在服务器硬件上&#xff0c;而不是操作系统之上&#xff…...

每日一题——矩阵最长递增路径

矩阵最长递增路径问题 题目描述数据范围&#xff1a;进阶要求&#xff1a;示例示例 1示例 2 题解思路算法步骤&#xff1a;代码实现代码解释复杂度分析总结 题目描述 给定一个 n 行 m 列的矩阵 matrix&#xff0c;矩阵内所有数均为非负整数。你需要在矩阵中找到一条最长路径&a…...

设置ollama接口能外部访问

为了配置Ollama以允许外网访问&#xff0c;你可以按照以下步骤进行操作&#xff1a; ‌确认Ollama服务已正确安装并运行‌&#xff1a; 使用以下命令检查Ollama服务的状态&#xff1a; bash Copy Code systemctl status ollama如果服务未运行&#xff0c;使用以下命令启动它&…...

TOML介绍

0 Preface/Foreword TOML&#xff0c;一种配置文件格式。Toms Obvious Minimal Language. 1 介绍 TOML: Toms Obvious Minimal Language&#xff0c;“显而易见的最小化语言 ” JSON&#xff1a;不支持注释 YAML&#xff1a;过于复杂...

macOS部署DeepSeek-r1

好奇&#xff0c;跟着网友们的操作试了一下 网上方案很多&#xff0c;主要参考的是这篇 DeepSeek 接入 PyCharm&#xff0c;轻松助力编程_pycharm deepseek-CSDN博客 方案是&#xff1a;PyCharm CodeGPT插件 DeepSeek-r1:1.5b 假设已经安装好了PyCharm PyCharm: the Pyth…...

从云原生到 AI 原生,谈谈我经历的网关发展历程和趋势

作者&#xff1a;谢吉宝&#xff08;唐三&#xff09; 编者按&#xff1a; 云原生 API 网关系列教程即将推出&#xff0c;欢迎文末查看教程内容。本文整理自阿里云智能集团资深技术专家&#xff0c;云原生产品线中间件负责人谢吉宝&#xff08;唐三&#xff09; 在云栖大会的精…...

京东 旋转验证码 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 使用的第三方接码平台识别…...

R18 XR L1 enhancement

这篇是R18 XR的最后一部分,主要是L1方面的增强。 这部分增强大概的背景如下。 一些 XR 应用(例如增强现实)不仅在 DL 方向需要高数据速率,在 UL 方向也需要高数据速率。如果应用需要在 UL 方向传输视频流量,则 UL 中支持的 XR 用户数量可能非常有限。因此,增加有限的时间…...

利用Java爬虫按图搜索1688商品(拍立淘):实战案例指南

在电商领域&#xff0c;按图搜索功能&#xff08;如1688的“拍立淘”&#xff09;为用户提供了更直观、便捷的购物体验。通过上传图片&#xff0c;用户可以快速找到与图片相似的商品。本文将详细介绍如何利用Java爬虫技术实现按图搜索1688商品&#xff0c;并获取其详情数据。 …...

算法-计算字符的最短距离

力扣题目&#xff1a;821. 字符的最短距离 - 力扣&#xff08;LeetCode&#xff09; 给你一个字符串 s 和一个字符 c &#xff0c;且 c 是 s 中出现过的字符。 返回一个整数数组 answer &#xff0c;其中 answer.length s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 …...

sqlilabs--小实验

一、先盲注判断 ?id1 and sleep(2)-- 如果发现页面存在注点&#xff0c;使用时间盲注脚本进行注入 import requestsdef inject_database(url):name for i in range(1, 20): # 假设数据库名称长度不超过20low 48 # 0high 122 # zmiddle (low high) // 2while low &l…...

【JavaScript爬虫记录】记录一下使用JavaScript爬取m4s流视频过程(内含ffmpeg合并)

前言 前段时间发现了一个很喜欢的视频,可惜网站不让下载,简单看了一下视频是被切片成m4s格式的流文件,初步想法是将所有的流文件下载下来然后使用ffmpeg合并成一个完整的mp4,于是写了一段脚本来实现一下,电脑没有配python环境,所以使用JavaScript实现,合并功能需要安装ffmpeg,…...

腿足机器人之一- 机械与电子组件概览

腿足机器人之一机械与电子组件概览 引言机械组件骨架材料关节设计关节机械组件轴承&#xff08;ings&#xff09;连杆&#xff08;Linkages&#xff09;齿轮&#xff08;Gears&#xff09; 电气组件电机控制器传感器 四足机器人设计双足机器人设计波士顿Atlas机器人 引言 腿足…...

利用二分法+布尔盲注、时间盲注进行sql注入

一、布尔盲注&#xff1a; import requestsdef binary_search_character(url, query, index, low32, high127):while low < high:mid (low high 1) // 2payload f"1 AND ASCII(SUBSTRING(({query}),{index},1)) > {mid} -- "res {"id": payloa…...