编译原理AST以Babel为例进行解读、Webpack中自定义loader与plugin
AST树详解
编译原理
主要研究如何将高级编程语言的源代码转换为机器能理解的目标代码
(通常是二进制代码或中间代码)。编译器的底层实现通常包含多个阶段,包括词法分析、语法分析、语义分析和代码生成
。
一、AST的核心概念与作用
AST(Abstract Syntax Tree,抽象语法树) 是源代码语法结构的树状抽象表示
,每个节点对应代码中的一个语法单元(如表达式、变量声明、函数调用等)。其核心作用是将代码结构化,便于程序分析和转换。
关键特性:
• 去冗余:忽略代码中的空格、注释等非语法元素,聚焦结构。
• 可操作性
:通过遍历和修改AST节点
,实现代码优化、语法转换等。
二、AST的生成与处理流程
1. 词法分析(Lexical Analysis)
将代码拆解为Token序列
(如关键字、标识符、运算符等)。例如,const sum = (a, b) => a + b
会被拆解为const
、sum
、=
、=>
等Token。
2. 语法分析(Syntax Analysis)
根据语法规则将Token构建成AST树
。例如,Babel使用@babel/parser
生成ES6代码的AST,Vue将模板解析为包含元素、指令的AST节点
。
3. 转换与优化
• Vue模板优化:标记静态节点(如纯文本元素)
,减少虚拟DOM的Diff计算
。
• ES6转ES5:通过AST将箭头函数转换为普通函数,类语法转为构造函数。
4. 代码生成
将修改后的AST转换为目标代码。例如,Vue生成渲染函数,Babel输出ES5代码
。
三、AST在前端生态中的核心应用
1. Vue的模板编译
• 模板解析:Vue将<template>
转换为AST,标记动态绑定(如{{ }}
、v-if
)。
• 静态提升:AST分析静态节点,提升到渲染函数外部,减少重复渲染开销。
• 源码迁移:AST工具可自动化迁移Vue 2到Vue 3的非兼容语法(如全局指令注册方式)。
2. ES6与Babel
Babel详解
Babel是一个强大的JavaScript编译器,通过插件化的架构和预设功能,实现了对现代JavaScript代码的向后兼容转换。它与构建工具的集成使用,可以自动化代码转换和构建过程,提高开发效率。同时,Babel紧跟ECMAScript规范的发展,支持最新的JavaScript语言特性,帮助开发者在保持兼容性的同时使用最新的JavaScript语法和特性。
• 语法降级:Babel通过AST将ES6+代码(如箭头函数、解构赋值)转换为ES5兼容代码。
• 代码优化:AST支持Tree-shaking(移除未使用代码)、常量折叠等优化。
3. 其他工具链
• Webpack:依赖AST分析模块导入/导出关系,实现按需加载
。
• ESLint/Prettier:基于AST实现代码风格检查与格式化
。
4.Tree-shaking中的应用
Tree-shaking是一种通过消除未使用代码来优化前端打包体积的技
术,其核心依赖于抽象语法树(AST)对代码的静态分析能力
。以下从AST的解析、转换、优化三个阶段,结合具体技术场景,详细说明其作用机制:
一、AST解析:构建代码结构化表示
AST将源代码转化为树状数据结构
,每个节点对应代码中的语法单元(如变量声明、函数调用等)。在Tree-shaking中,AST的解析作用包括:
- 模块依赖分析
构建工具(如Webpack、Rollup)通过AST遍历入口文件,递归解析import/export
语句,生成模块依赖图。例如,import { add } from './math.js'
会被解析为AST节点,明确add
函数的引用关系。 - 语法结构标记
AST将代码的语法特征结构化,如将export const subtract = (a, b) => a - b
标记为导出节点,便于后续分析是否被引用。
二、AST转换:识别与标记未使用代码
基于AST的静态分析,Tree-shaking通过以下步骤实现代码优化:
- 导出节点标记
遍历AST识别所有导出节点(如export
语句),并与模块依赖图对比,标记未被引用的导出
。例如,若仅add
函数被使用,则subtract
的导出节点会被标记为待移除。 - 副作用检测
AST可分析代码是否具有副作用(如修改全局变量、执行I/O操作)。例如,纯函数(无副作用)可直接删除
,而包含console.log
的代码可能被保留。 - 作用域分析
通过AST的作用域链追踪变量引用关系。例如,未被调用的函数或未被读取的变量会被标记为“死代码”。
三、AST优化:生成精简代码
完成标记后,构建工具对AST进行剪枝和重构:
- 节点删除
直接移除标记为未使用的AST节点及其子节点。例如,删除未被引用的subtract
函数及其参数声明。 - 代码压缩
基于AST的优化能力进一步简化代码结构,如删除冗余变量、合并重复逻辑。 - 目标代码生成
将优化后的AST转换为最终代码。例如,Webpack通过TerserPlugin
将处理后的AST生成ES5兼容代码。
关键技术优势与挑战
-
优势
• 精确性:AST的结构化特性避免了字符串匹配的误判,确保仅删除确未使用的代码。• 复杂语法支持:可处理箭头函数、解构赋值等ES6+语法,适应现代前端开发需求。
• 跨工具整合:AST为Webpack、Babel、ESLint等工具提供统一分析基础,支持全链路优化。
-
挑战
• 动态代码处理:如eval()
或import()
动态导入可能导致Tree-shaking失效,需配合静态分析策略(采用静态字符串路径、按需导入、结合Webpack魔法注释、优先使用es)。• 副作用管理:需通过
/*#__PURE__*/
注释或package.json
的sideEffects
字段显式声明副作用模块。
实际应用案例
场景1:Vue 3组件优化
Vue模板编译时,AST标记静态节点(如纯文本元素),Tree-shaking移除未使用的组件代码,减少生产包体积。
场景2:Lodash按需引入
使用import { debounce } from 'lodash-es'
(ES模块)替代全量导入,AST识别仅debounce
被引用,移除其他未使用函数。
总结
开发者可通过以下实践提升Tree-shaking效果:
- 优先使用ES6模块语法(
import/export
); - 避免动态导入与副作用代码;
- 选择支持ES模块的第三方库(如
lodash-es
替代lodash
)。
四、AST的实战案例
案例1:Vue模板编译
// 输入:Vue模板
<template><div>{{ message }}</div>
</template>// 输出:AST结构
{type: 'Root',children: [{type: 'Element',tag: 'div',children: [{type: 'Interpolation',content: 'message'}]}]
}
通过AST标记message
为动态节点,生成对应渲染函数。
案例2:ES6转ES5(Babel)
// 输入:ES6箭头函数
const sum = (a, b) => a + b;// AST转换步骤:
// 1. 解析为AST(箭头函数节点)
// 2. 转换为普通函数表达式节点
// 3. 生成ES5代码:
const sum = function(a, b) { return a + b; };
// 原始代码
const add = (a, b) => a + b; // 1. 解析为AST
const parser = require('@babel/parser');
const ast = parser.parse(code); // 2. 遍历AST,修改节点
const traverse = require('@babel/traverse').default;
traverse(ast, { ArrowFunctionExpression(path) { // 将箭头函数替换为函数表达式 path.replaceWith({ type: 'FunctionExpression', params: path.node.params, body: path.node.body }); }
}); // 3. 生成新代码
const generator = require('@babel/generator').default;
const newCode = generator(ast).code; // 输出结果
const add = function(a, b) { return a + b; };
此过程依赖@babel/core
和@babel/preset-env
的AST处理能力。
五、总结
AST是前端工具链的基石,其核心价值在于:
• 标准化代码表示:统一处理不同语法(如Vue模板、JSX、ES6)。
• 高效静态分析:支持代码优化、错误检查、自动化重构等。
• 跨平台兼容
:通过AST转换实现代码的多环境适配(如浏览器兼容、跨端框架)。
在Vue和ES6场景中,AST帮助开发者实现从代码迁移到性能优化的全链路能力,是前端工程化不可或缺的技术。
Webpack中自定义loader与plugin
Compiler&Compilation&自定义插件
loader本质是函数:输入为原始代码,经过处理,返回目标代码
plugin本质是类对象:实现apply方法,有一系列webpack打包的生命钩子
当然可以!我将首先对你这段内容进行完善,然后基于此写出一篇完整、适合博客发布的文章,结构清晰、适合初中高级开发者阅读。
在使用 Webpack 构建前端项目的过程中,Loader
和 Plugin
是两个核心概念,它们分别承担着不同的职责:Loader
主要用于对模块的源代码进行转换处理,而 Plugin
则用于扩展 Webpack 的打包能力与生命周期管理。理解并掌握它们的自定义方式,有助于开发者灵活应对各种复杂的构建需求。
一、什么是 Loader?
Loader 本质上是一个导出为函数的模块,用于将源文件内容(字符串形式)转换为 JavaScript 能理解的模块。
Loader 的特点:
- 它是一个函数,接收原始源代码作为参数。
- 可以链式调用多个 loader,从右向左依次处理。
- 常用于处理非 JavaScript 类型的文件,如
.css
、.scss
、.vue
、.ts
等。
Loader 的基本结构:
// my-loader.js
module.exports = function (source) {// source 是读取到的原始内容const result = source.replace(/foo/g, 'bar');return result;
};
添加到 webpack.config.js:
module.exports = {module: {rules: [{test: /\.txt$/,use: path.resolve(__dirname, 'loaders/my-loader.js')}]}
};
你也可以使用 this
提供的工具函数(如缓存、异步等)来编写更复杂的逻辑。
二、什么是 Plugin?
Plugin 本质上是一个类,它通过 apply
方法接入 Webpack 的编译生命周期,在合适的时机做一些定制化操作,如:生成额外的文件、优化打包结果、清理目录等。
Plugin 的特点:
- 是一个拥有
apply(compiler)
方法的类。 - 可以接入 Webpack 提供的各种生命周期钩子,如
emit
、compilation
、done
等。 - 更适合做构建过程中的增强或变更,而非模块转换。
Plugin 的基本结构:
class MyPlugin {apply(compiler) {compiler.hooks.emit.tap('MyPlugin', (compilation) => {// 在打包资源生成前执行console.log('This is MyPlugin working!');});}
}module.exports = MyPlugin;
使用方法:
const MyPlugin = require('./plugins/my-plugin');module.exports = {plugins: [new MyPlugin()]
};
你可以结合 Webpack 提供的钩子机制与 Node.js 能力,实现灵活的功能,比如自动写入文件、内容注入、性能分析等。
三、Loader 与 Plugin 的对比总结
对比项 | Loader | Plugin |
---|---|---|
本质 | 函数(function) | 类(class) |
作用 | 处理模块内容(代码转换) | 参与构建流程(生命周期钩子) |
使用方式 | 配置在 module.rules 中 | 配置在 plugins 数组中 |
典型用途 | 编译 TS、处理 CSS、加载图片等 | 生成 HTML、清理目录、进度条等 |
四、自定义 Loader 和 Plugin 的应用场景举例
自定义 Loader 场景:
- Markdown 转 HTML
- 实现代码注释剔除功能
- 国际化代码替换
自定义 Plugin 场景:
- 构建结束自动发送通知
- 在构建目录中写入自定义 manifest 文件
- 构建时检测重复依赖并输出警告
五、结语
掌握 Loader 和 Plugin 的原理与自定义能力,是使用 Webpack 构建系统的一项高级技能。Loader 关注“如何处理每一个模块”,而 Plugin 更偏向于“如何控制整个构建流程”。当内置能力无法满足需求时,学会自己动手,才是工具为我所用的真正体现。
相关文章:
编译原理AST以Babel为例进行解读、Webpack中自定义loader与plugin
AST树详解 编译原理 主要研究如何将高级编程语言的源代码转换为机器能理解的目标代码(通常是二进制代码或中间代码)。编译器的底层实现通常包含多个阶段,包括词法分析、语法分析、语义分析和代码生成。 一、AST的核心概念与作用 AST&#…...
牛客周赛 Round 92
目录 A-小红的签到题 代码 B-小红的模拟 代码 C-小红的方神题 代码 D-小红的数学题 代码 无注释版 有注释版 E-小红的ds题 代码 无注释版 有注释版 A-小红的签到题 代码 #include<bits/stdc.h> using namespace std; int main(){int n;cin>>n;cha…...
面试题:C++虚函数可以是内联函数吗?
目录 1.引言 2.示例 3.总结 1.引言 为什么C的虚函数和内联函数这两个看似矛盾的特性能否共存?这个问题实际上触及了C编译期优化与运行时多态性之间的微妙平衡。我发现这个问题不仅是面试中的常见陷阱,更是理解C深层机制很好的一个点。 虚函数可以被声…...
蚁群算法赋能生鲜配送:MATLAB 实现多约束路径优化
在生鲜农产品配送中,如何平衡运输效率与成本控制始终是行业难题。本文聚焦多目标路径优化,通过 MATLAB 实现蚁群算法,解决包含载重限制、时间窗约束、冷藏货损成本的复杂配送问题。代码完整复现了从数据生成到路径优化的全流程,助…...
前苹果首席设计官回顾了其在苹果的设计生涯、公司文化、标志性产品的背后故事
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
《基于 Kubernetes 的 WordPress 高可用部署实践:从 MariaDB 到 Nginx 反向代理》
手把手教你用 Kubernetes 部署高可用 WordPress 博客 本实验通过 Kubernetes 容器编排平台,完整部署了一个高可用的 WordPress 网站架构,包含 MariaDB 数据库、WordPress 应用和 Nginx 反向代理三大核心组件。实验涵盖了从基础环境准备到最终服务暴露的…...
文件上传总结
攻击与绕过方式 一、条件竞争 攻击原理:在上传文件的同时利用代码逻辑中的时序问题(如 unlink() 删除操作)触发条件竞争,从而实现上传恶意文件并绕过限制。 示例测试源码: 以下为测试文件上传功能的 PHP 源码ÿ…...
在文档里如何引用在线SVG甘特图
在文档里如何引用在线SVG甘特图 介绍 本文将详细介绍如何快速创建一个功能强大的在线甘特图,并将其嵌入到其他文档(如 Notion、Wiki、Qiita、GitHub、Obsidian、Email 等)中。只要目标工具支持引用网络图片,你就可以轻松实现这一…...
Spring AI 与 Groq 的深度集成:解锁高效 AI 推理新体验
Spring AI 与 Groq 的深度集成:解锁高效 AI 推理新体验 前言 在人工智能飞速发展的当下,AI 推理的效率和性能成为开发者关注的焦点。Groq 作为一款基于 LPU™ 的超快速 AI 推理引擎,凭借其强大的性能,能够支持各类 AI 模型&…...
101alpha---第10
rank(((0 < ts_arg_min(ts_delta(close, 1), 4)) ? ts_delta(close, 1) : ((ts_arg_max(ts_delta(close, 1), 4) < 0) ? ts_delta(close, 1) : (-1 * ts_delta(close, 1))))) alpha 那么我们来看具体含义 吧 rank(((0 < ts_arg_min(ts_delta(close, 1), 4)) ? …...
vim中的查找
在 Vim 中,使用 n 键可以按正向(向下)继续查找下一个匹配项。若要反向(向上)查找,可以使用以下方法: 1. 使用 N 键反向查找 在查找命令(如 /keyword)后,按下…...
什么是IP专线?企业数字化转型的关键网络基础设施
为什么企业需要IP专线? 在当今数字化浪潮席卷全球的背景下,企业网络需求正经历着前所未有的变革。传统网络架构已难以满足现代企业对高效、安全、灵活网络服务的需求,IP专线正是在这一背景下应运而生的关键网络解决方案。 专线服务本质上是…...
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
目录 Linux软件包管理器 - yum Linux下载软件的方式 认识yum 查找软件包 安装软件包 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 vim命令模式各命令汇总 vim底行模式各命令汇总 Linux编译器 - gcc/g …...
5.11 - 5.12 JDBC+Mybatis+StringBoot项目配置文件
JDBC: 预编译SQL优点:安全,性能更高。 在cmd里面输入java-jar就可以运行jar包。 Mybatis: 持久层框架。用于简化JDBC的开发。 数据库连接池里面放置的是一个一个Connection连接对象。(连接池中的连接可以复用&#…...
判断一个数组有没有重复值
要判断一个数组是否包含重复值,你可以使用多种方法。以下是一些常用的方法: 方法 1:使用 Set Set 是一种集合数据结构,它只存储唯一的值。因此,你可以将数组转换为 Set,然后比较 Set 的大小与数组的长度。…...
51c大模型~合集127
我自己的原文哦~ https://blog.51cto.com/whaosoft/13905076 #Executor-Workers架构 图解Vllm V1系列2 本文详细介绍了vllm v1的Executor-Workers架构,包括Executor的四种类型(mp、ray、uni、external_launcher)及其适用场景ÿ…...
Spring急速入门
Spring 是 企业级开发的一站式框架,核心是 IOC(控制反转) 和 AOP(面向切面编程) 一、Spring 核心:IOC 理论 1. 什么是 IOC? IOC(Inversion of Control,控制反转&…...
#在 CentOS 7 中手动编译安装软件操作及原理
在 CentOS 7 中,手动编译安装软件(即从源代码编译安装)是一种高度灵活的方式,适用于需要定制化软件功能、优化性能或安装官方仓库未提供的软件版本的场景。以下是针对手动编译安装的详细说明,包括原理、步骤、注意事项…...
【Kubernetes】初识基础理论(第一篇)
前言 单机容器编排: docker-compose 容器集群编排: docker swarm、mesosmarathon、kubernetes 应用编排: ansible 一、Kubernetes概述 Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的…...
配置集群(yarn)
在配置 YARN 集群前,要先完成以下准备工作: 集群环境规划:明确各节点的角色,如 ResourceManager、NodeManager 等。网络环境搭建:保证各个节点之间能够通过网络互通。时间同步设置:安装 NTP 服务࿰…...
按钮导航组件 | 纯血鸿蒙组件库AUI
摘要: 按钮导航组件(A_ButtonNav):可设置导航数据(含文本及路由),可设置按钮颜色、导航标题及导航子标题。 一、组件调用方式 1.1.极简调用: 用 A_ButtonNav 调用“按钮导航组件”,只需要给属性 data (导…...
自适应主从复制模拟器的构建与研究
自适应主从复制模拟器的构建与研究 摘要: 本文旨在构建一个自适应主从复制模拟器,深入研究主从复制原理及优化方法。从研究者视角出发,详细阐述模拟器的设计、实现与实验过程,通过表格、图表及代码等辅助手段,逐步探讨如何在不同网络条件和负载下,自动调整主从复制参数和…...
015枚举之滑动窗口——算法备赛
滑动窗口 最大子数组和 题目描述 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 原题链接 思路分析 见代码注解 代码 int maxSubArray(vector<int>& num…...
【Dv3Admin】工具视图配置文件解析
在开发后台管理系统时,处理复杂的 CRUD 操作是常见的需求。Django Rest Framework(DRF)通过 ModelViewSet 提供了基础的增删改查功能,但在实际应用中,往往需要扩展更多的功能,如批量操作、权限控制、查询优化等。dvadmin/utils/viewset.py 模块通过继承并扩展 ModelViewS…...
在MyBatis Plus里处理LocalDateTime类型
在MyBatis Plus里处理LocalDateTime类型 在MyBatis Plus里处理LocalDateTime类型时,你要确保数据库字段和Java实体类属性之间的类型映射是正确的。下面为你介绍处理这种情况的方法: 1. 数据库字段类型对应设置 要保证数据库字段类型和LocalDateTime相…...
编程技能:字符串函数03,strncpy
专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏,故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 (一)WIn32 专栏导航 上一篇:编程技能:字符串函数02,strcpy 回到目录…...
edge设置位IE模式打开网页
打开Edge浏览器->在浏览器工具栏右键->自定义工具栏->外观->选择要在工具栏上显示的按钮->找到“Internet Explorer 模式”按钮->开启,将其添加到工具栏中...
代码随想录训练营第二十二天| 101.对称二叉树 100.相同的树
101.对称二叉树: 文档讲解:代码随想录|101.对称二叉树 视频讲解:新学期要从学习二叉树开始! | LeetCode:101. 对称二叉树_哔哩哔哩_bilibili 状态:已做出 思路: 这道题目我初始做的时候想着使用…...
nvm管理node版本
To manage Node.js versions on Windows, I recommend using nvm-windows (Node Version Manager for Windows). Here’s how we can handle this: First, let’s install nvm-windows. I’ll propose a command to check if it’s already installed: nvm versionGreat! I s…...
智能手表测试计划文档(软/硬件)
📄 智能手表测试计划文档(软/硬件) 项目名称:Aurora Watch S1 文档编号:AW-S1-QA-TP-001 编制日期:2025-xx-xx 版本:V1.0 编写人:xxx(测试主管) 一、测试目标…...
基于大模型的原发性醛固酮增多症全流程预测与诊疗方案研究
目录 一、引言 1.1 研究背景与意义 1.2 国内外研究现状 1.3 研究目的与方法 二、原发性醛固酮增多症概述 2.1 疾病定义与发病机制 2.2 临床表现与诊断标准 2.3 流行病学特征 三、大模型预测原理与技术 3.1 大模型简介 3.2 预测原理与算法 3.3 数据收集与预处理 四…...
spring中的@Lazy注解详解
一、核心功能与作用 Lazy 注解是 Spring 框架中用于延迟 Bean 初始化的核心工具,通过将 Bean 的创建推迟到首次使用时,优化资源利用和启动性能。其核心功能包括: 延迟初始化 默认情况下,Spring 在容器启动时立即初始化所有单例 …...
Docker快速入门与应用
1. 什么是 Docker? Docker 就像一个“魔法箱子”,可以把你开发的应用(代码、环境、配置)打包成一个标准化的容器,这个容器可以在任何支持 Docker 的系统上运行,无需担心环境差异导致的问题。 类比…...
判断一个数是不是素数的最高效的算法
判断一个数是否是素数,有从简单到复杂多种方法。最高效的算法取决于输入规模(是几个亿以内的数,还是上百位的大整数),我会按实用场景分类讲解: ✅ 常规范围内(比如 ≤ 1e12)判断素数…...
《Head First 设计模式》第一章 - 笔记
本书是本人写的设计模式的笔记,写下核心要点,如果你掌握过设计模式,想快速阅读本书内容,这个笔记适合你阅读。如果你是新手,有 java 基础和 oo 设计原则基础,你适合跟我一样从零阅读本书。 第一章 策略模式…...
GPT系列:自然语言处理的演进与多模态的探索
GPT系列:自然语言处理的演进与多模态的探索 GPT系列的发展一、GPT-1 :通过生成式的预训练改进自然语言GPT-1的动机做一个预训练模型的难点GPT-1的微调模式GPT-1的训练数据Bert 二、GPT-2语言模型是非监督的GPT-2的动机引入promptGPT-2模型架构的改变GPT-…...
Linux驱动:驱动编译流程了解
要求 1、开发板中的linux的zImage必须是自己编译的 2、内核源码树,其实就是一个经过了配置编译之后的内核源码。 3、nfs挂载的rootfs,主机ubuntu中必须搭建一个nfs服务器。 内核源码树 解压 tar -jxvf x210kernel.tar.bz2 编译 make x210ii_qt_defconfigmakeCan’t use ‘…...
【MySQL】数据库基础
目录 1.什么是数据库2.见一见数据库3.服务器、表、库之间的关系4.MySQL架构5.sql语句分类6.查看MySQL存储引擎6.1 查看存储引擎6.2 常见存储引擎对比 1.什么是数据库 概念:数据库一般是指,在磁盘或者内存中存储的特定结构组织的数据 – 将来在磁盘上存储…...
1.1 文章简介
前因后果链 行业需求 → 技能断层 → 课程设计响应 (高薪岗位要求数学基础) → (符号/公式理解困难) → (聚焦原理与应用) 行业驱动因素 • 前因:机器学习/AI等领域的高薪岗位激增,但数学能力成为主要门槛 • 关键矛盾:算法论文中的数学…...
laravel 中使用的pdf 扩展包 laravel-snappy(已解决中文乱码)
Centos7 安装 wkhtmltopdf 1、先查看系统是 32 位的还是 64 位的 uname -a2、通过 composer 安装 wkhtmltopdf 32位: $ composer require h4cc / wkhtmltopdf-i386 0.12.x $ composer require h4cc / wkhtmltoimage-i386 0.12.x 64位: $ composer require h4cc/wkhtmltopdf-…...
java反序列化commons-collections链6
cc链6,最好用的cc链,因为它不受jdk版本的限制和cc版本的限制,前半段很像urldns链,后半段是cc1链 先来看一下它的利用链 Gadget chain:java.io.ObjectInputStream.readObject()java.util.HashSet.readObject()java.util.HashMap.p…...
WebSocket的原理及QT示例
一.WebSocket 介绍 1.概述 WebSocket 是一种在单个 TCP 连接上进行全双工通讯的协议,它在 2011 年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。与传统的 HTTP 协议不同,WebSocket 允许服务器和客户端之间进行实时、双向的数据传输&a…...
css 点击后改变样式
背景: 期望实现效果:鼠标点击之后,保持选中样式。 实现思路:在css样式中,:active 是一种伪类,用于表示用户当前正在与被选定的元素进行交互。当用户点击或按住鼠标时,元素将被激活,此…...
AI 在模仿历史语言方面面临挑战:大型语言模型在生成历史风格文本时的困境与研究进展
概述 在当今数字化时代,人工智能(AI)技术在诸多领域展现出了强大的能力,但在处理历史语言这一特定任务时,却遭遇了不小的挑战。美国和加拿大的研究人员通过合作发现,像 ChatGPT 这样的大型语言模型&#x…...
C++.Windows图形
Windows图形 1. 基础知识1.1 Windows图形编程基础1.2 GDI与GDI1.3 窗口消息处理2.1 注册窗口类2.2 创建窗口2.3 显示窗口3.1 创建按钮3.2 按钮消息处理4.1 设置窗口透明度4.2 透明窗口示例5.1 使用区域创建异形窗口5.2 异形窗口示例6.1 GDI抗锯齿设置6.2 抗锯齿绘图示例7.1 Dir…...
【Vue3】使用vite创建Vue3工程、Vue3基本语法讲解
一、什么是Vite Vite是新一代前端构建工具,官网地址:Vite中文网,vite的优势如下: 轻量快速的热重载(HMR),能实现极速的服务启动对TypeScript、JSX、CSS等支持开箱即用真正的按需编译ÿ…...
专题二:二叉树的深度优先搜索
以leetcode2331题为例 题目分析: 以第一个示例为例 算法原理分析: 从宏观角度,也就是我的算法之回溯的第一篇 我们发现我们在研究示例的时候,必须从下往上推 也就是我在研究一个结点是true还是false的时候,必须…...
Termius ssh连接服务器 vim打开的文件无法复制问题
你的问题是: • 在 Termius (macOS) SSH 连接到 VMware Ubuntu,使用 vim 打开 .cpp 文件时,可以复制文本; • 但在 Windows 10 上 SSH 到 VMware 的 Red Hat 6.4 时,复制操作无效。 ⸻ 🎯 初步分析 复制…...
搭建大数据学习的平台
一、基础环境准备 1. 硬件配置 物理机:建议 16GB 内存以上,500GB 硬盘,多核 CPU虚拟机:至少 3 台(1 主 2 从),每台 4GB 内存,50GB 硬盘 2. 操作系统 Ubuntu 20.04 LTS 或 CentOS…...
Matlab 模糊控制节水洗衣机模型
1、内容简介 Matlab 232-模糊控制节水洗衣机模型 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...