前端项目重构的深度思考和复盘

在这里插入图片描述
摘要:

项目重构是每一家稳定发展的互联企业的必经之路, 就像一个产品的诞生, 会经历产品试错和产品迭代 一样, 随着业务或新技术的不断发展, 已有架构已无法满足更多业务扩展的需求, 所以只有通过重构来让产品“进化”, 才能跟上飞速发展的时代浪潮.

技术因素

  1. 早期技术团队在技术选型上的误判(常发生于MVP类型的产品快速上线导致的技术调研不够充分)
  2. 新老技术框架的更替(比如从 jquery 迁移到 vue/react)
  3. 技术团队交接出现的断层(老技术团队的架构设计更不上新技术团队的发展, 出现架构上的“平替”)
  4. 技术架构升级(比如随着业务发展, 由传统的MPA应用转为基于微前端模式的SPA应用)
  5. 安全,性能,代码质量等原因导致的技术重构

产品因素

  1. 产品形态调整(比如由纯PC应用转为响应式应用, 或者从H5到支持跨端)
  2. 产品业务调整(非常常见的重构理由之一)
  3. 产品指标调整(如兼容性, 性能指标等导致的代码重构)

上面是我列出来的比较典型的重构场景, 也是我们未来在设计产品技术架构之前需要考虑的方面. 为了提高自己设计的架构稳定性, 我们需要提前和产品沟通明确, 以降低后期重构和维护成本.

所以:

  1. 能做规范的一定要严格做好规范
  2. 在设计架构之前, 一定要充分理解业务场景, 明确产品的技术交付指标
  3. 架构设计以可溯源 为基本要求
  4. 不要盲目追求最好的方案, 以局部最优解为工程设计理念

做项目重构之前, 需要有哪些准备

  • 对项目所使用的框架语言有相对深入的理解和掌握
  • 有一定的前端工程化经验(如webpack, vite, gulp, nodejs, babel, AST等有一定的研究)
  • 熟悉常用的web性能优化方案
  • 熟悉常见的设计模式和前端编码规范
  • 熟悉前端主流的技术框架的设计原理和工程设计思想

不同类型项目重构的方法论

1. 业务系统自身的重构

业务代码优化:
业务代码优化主要是针对一些核心业务代码, 进行流程上, 逻辑上的重构, 让它更具可读性和维护性, 同时保证业务操作的兼容性, 具体方案如下:
1、复杂业务逻辑需要编写注释
2、代码中访问性属性提供兼容逻辑(常见的比如访问对象属性, a.b.c, 如果a,b为非对象则整段代码将报错)
3、代码结构优化(比如冗长的if else 或者“回调地狱” 可以采用适配器模式或者es6+语法来优化)
4、方法参数调优(一个函数有多个参数, 可以使用参数对象来提高可读性,降低使用偏差)
5、业务代码性能优化(复杂后台系统比如低代码类产品, 前端需要处理很多数据和逻辑, 此时可以用合适的数据结构和算法优化js计算)
6、函数式编程思想优化业务函数(可选)
7、业务代码进行单元测试, 提高代码质量(可选)

代码规范:
早期可能由某名研发单独负责的项目, 对代码规范和格式要求不是很高, 但是需要考虑后期团队扩容带来的协作开发问题, 这个时候如果没有统一的规范, 不同研发小伙伴可能写出的代码千奇百怪, 导致后期维护成本巨大, 尤其是涉及到需要维护他人代码时.
所以我们重构的另一个目标就是降低代码理解成本, 保证项目代码在阅读时就像同一个写出来的, 这样对后期逻辑复用, 组件解耦, 问题定位以及业务代码维护将非常有帮助.:
1、代码格式规范(如eslint)
2、逻辑语法类型约束(如typescript)
3、代码规范(如css命名规范OOCSS, BEM等, 文件命名规范, js变量命名复规范等)
4、git 提交规范(常见的是在git hooks的提交阶段对提交格式等进行校验)
这些都是需要结合自身团队和项目来定的

工程化优化:
早期可能由某名研发单独负责的项目, 对代码规范和格式要求不是很高, 但是需要考虑后期团队扩容带来的协作开发问题, 这个时候如果没有统一的规范, 不同研发小伙伴可能写出的代码千奇百怪, 导致后期维护成本巨大, 尤其是涉及到需要维护他人代码时.
所以我们重构的另一个目标就是降低代码理解成本, 保证项目代码在阅读时就像同一个写出来的, 这样对后期逻辑复用, 组件解耦, 问题定位以及业务代码维护将非常有帮助.:
1、由于业务不断增加, 系统的复杂性加大导致的本地运行和打包速度越来越慢
2、由于项目代码量的增加导致页面臃肿, 需要进行合理的拆分
3、基于已有的工程经验沉淀, 需要对工程化配置做进一步升级, 优化
4、老旧脚手架无法适应当前的项目生产效率

针对以上场景, 进行一些解决方案:
由于业务不断增加, 系统的复杂性加大导致的本地运行和打包速度越来越慢

针对这种情况, 我们可以借助 speed-measure-webpack-plugin 插件,它可以分析 webpack 的总打包耗时以及每个 plugin 和 loader 的打包耗时,从而让我们对打包时间较长的部分进行针对性优化。

同时默认情况react, react-dom, react-router 等公共模块在每次构建都会参与打包, 这些实际上是没有必要的, 我们可以将其传到 cdn上, 从而减少webpack 的打包”工作量“.

我们可以安装 html-webpack-externals-plugin 来实现将指定模块从打包列表中排除, 具体用法如下:

const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');module.exports = {// ...其他配置代码plugins: [new HtmlWebpackExternalsPlugin({externals: [{module: 'react',entry: 'https://cdn.xxxx.cn/umd/react.production.min.js',global: 'React',},{module: 'react-dom',entry:'https://cdn.xxxx.cn/umd/react-dom.production.min.js',global: 'ReactDOM',},],}),],
};

为了追求更惊一步的打包效率, 我们可以使用并行的方式构建, 同样 webpack 生态也提供了对应的模块 parallel-webpack. 具体用法大家可以看文档, 非常简单方便.

  • 配置并行压缩(terser-webpack-plugin, css-minimizer-webpack-plugin,
    html-minimizer-webpack-plugin
  • 等都支持parallel参数)
  • 预编译资源模块(可以利用webpack.DllPlugin来提前将公共模块打包以便后续直接复用)
  • 使用构建缓存(webpack5 内置的 cache 模块, 或者cache-loader)
  • 对打包体积进行分析, 以便有针对性的优化(如webpack-bundle-analyzer)

当然除了对已有构建工具的优化, 我们可以评估一下重构成本, 将构建内核替换vite等更高效的构建工具.

由于项目代码量的增加导致页面臃肿, 需要进行合理的拆分

针对项目代码量的增加导致页面臃肿, 我们可以从项目本身的角度, 对项目进行拆解, 将公共模块抽离为公用业务类库或者组件库:
在这里插入图片描述

除了对项目进行可复用性拆分之外, 我们还需要根据系统复杂量级, 近一步拆分项目, 比如将一个巨石工程拆分为多个子工程, 单独运行维护, 或者采用之前热点讨论的微前端的模式, 比如使用 qainkun, single-spa, Micro App, EMP, Garfish, Bit 这些优秀的微前端框架.

综上, 我们可以根据项目复杂度, 做如下优化:

  • 模块 & 组件化
  • 拆分子系统(已有架构不变的MPA模式)
  • 拆分子系统(微前端)

当然我们始终需要保持一个理念: 局部最优, 误增繁复.

基于已有的工程经验沉淀, 需要对工程化配置做进一步升级, 优化

这种情况主要是在项目发展稳定之后, 需要思考的重构方向, 比如早期由于业务场景单一, 很多公共配置都写在业务代码里的, 随着业务复杂之后, 很多模块都需要使用改配置或者变量, 比如:

const publicDomain = 'https://xxxx.vip';
const serverUrl = 'https://xxx.cn';// b.js
const publicDomain = 'https://xxxx.vip';// c.js
const appid = 'xxxxxxxx';
const website_Logo = 'http://h5.xxxx.cn/logo.png';

对于这种零散且固定的变量, 未来可能会被多个页面或者模块复用, 所以为了降低成本, 我们可以把这些通用配置提取到外层, 作为公共配置文件, 这样后期新项目也能享受开箱即用的配置体验.

拿我的亲身经验, 比如几年前我开发的低代码项目H5-Dooring, 有一些零散的配置信息分散在项目的各个角落, 后面经过几次重构优化之后, 整个项目只需要在配置文件中轻松配置内容, 即可一键控制页面的走向, 这里分享一下优化过后的配置文件:

// h5-dooring全局配置文件
define: {START_ENV,lang,// 配置h5端访问的域名h5Domain: 'h5.dooring.cn',// 设置当前版本号curVersion: dooringVersion,// 备案信息copyright: 'xxxxx-3',// 是否显示更新弹窗showUpdateModal: true,// 更新日志updateList:  ["1. 新增表格组件","2. 国际化优化","3. 表单详情页支持内部滚动","4. 个人图片库性能优化","5. 下载代码功能优化"],// 网站logo地址logo: 'http://cdn.xxxx.cn/dr/logo.ff7fc6bb.png',// 入口页面是否展示赞助品牌和版权提示showAdsAndTip: true,// 登录时获取登录码的二维码qrcode: 'http://cdn.xxxx.cn/dr%2Fcode1.png',// 友情链接展示friendLinks: [{name: 'V6',link: 'http://v6.xxx.cn/beta',title: '可视化大屏编辑器'},{name: 'Power',link: '/powernice',title: '文档编辑器'}],// 默认语言defaultLocale: 'zh-CN',langMap: langMap},

这样, 我们的工程化结果就可以让不同的技术小伙伴轻松的享受, 让项目创建的成本和自由度得到极大的提升.

老旧脚手架无法适应当前的项目生产效率

在这里插入图片描述
对于这种场景, 我们就需要对脚手架自身有更多的研究和了解, 比如熟悉webpack设计思想, 熟悉babel的工作流程, 熟悉 nodejs 开发工具链的一些模式等, 这里分享几个比较成熟的先进脚手架, 大家如果觉得老项目工程比较老旧, 可以往这几个方向重构:

  • 基于webpack5.0的项目脚手架
  • vite
  • umi4.0

如果大家对以上三种之一比较熟悉, 也可以基于他们二次封装成符合自身业务场景的DIY项目工具.

渲染层优化

  1. 提高首屏加载速度
  2. 白屏体验优化
  3. 大数据列表渲染优化
  4. api请求优化
  5. 动画性能优化
  6. dom过载导致的页面卡顿优化

以上是我之前遇到的一些渲染优化的维度, 接下来和大家一一介绍解决思路.

提高首屏加载速度

  1. 静态资源放cdn, 提高不同地域用户访问资源的速度
  2. 页面或路由懒加载, 降低首次加载单一页面的代码体积
  3. 静态资源(如图片, 视频等)懒加载
  4. 资源压缩(比如开启gzip模式)

当然还存在很多客观因素, 比如用户所在区域为弱网环境, 我们可以根据网速提供一个最小化弱网可替代页面, 来保证我们网站的可用性和可访问性.

白屏体验优化
对于白屏优化, 也有很多成熟的例子, 比如采用骨架屏:
在这里插入图片描述

如果我们的项目是基于 vue-cli 构建的,那么可以使用比较成熟的的 page-skeleton-webpack-plugin 方案,否则我们仍然可以选择 vue-router 提供的 vue-server-renderer.

当然你的项目是使用react的, 也可以轻松使用如 react-content-loader 这样的svg方案来定制自己的骨架屏.

除了骨架屏之外, 我们还可以提供一个模版页面或者加载动画, 以便在页面加载完成之前给用户一个优雅的过渡提示. 比如:
在这里插入图片描述
大数据列表渲染优化

对于一些中后台复杂的系统模块, 可能会涉及到一次渲染大量列表项或者多级组织树的情况:

在这里插入图片描述

尤其是在大公司或者大集团中出现的频率非常高, 这种情况我们就需要用到虚拟列表或者节点懒加载的方式了. 虚拟列表应用非常广泛, 目前也有几个成熟的方案大家可以直接使用:

  • vue virtual scroll list
  • react-virtualized
  • rc-virtual-list

如果你的项目目前还好没有使用这种方案, 不妨评估一下, 是否可以用这些方案为自己项目保驾护航.

api请求优化

api 请求优化主要正对这种场景: 页面的渲染依赖于某个或者某些请求的完成, 或者由于某个页面请求量过大导致每次重新进入页面都需要造成一定的性能开销.

对于这两种情况, 其实不仅仅是对浏览器渲染有影响, 还会极大的增加服务器的压力, 所以我们需要对请求或者页面进行一定范围的缓存.

比如说我们可以把不长变动的请求数据存在 indexedDB 中, 当第二次访问直接可以从 indexedDB 中拿到请求数据, 这样既降低了服务器压力, 也提高了二次渲染的效率.

动画性能优化

  • 优化精简 DOM 结构,合理布局
  • 使用 transform 代替 left,top 减少使用引起页面重排的属性
  • 开启硬件加速(比如设置transform: translateZ(0) 或者transform: translate3d(0,0, 0))
  • 尽量避免浏览器创建不必要的图形层
  • 尽量减少 js 动画,如需要,使用性能更友好的requestAnimationFrame
  • 使用 chrome performance 工具调试动画性能

由于dom动画有上限很低, 所以对于一些更复杂的动画渲染, 我们可以采用 svg 或者 canvas 来代替, 以降低 dom 对浏览器内存的占用.

dom过载导致的页面卡顿优化

一个页面如果dom数量过多, 会产生很多问题, 一方面会使得浏览器内存占用过高, 导致其他不相关的js逻辑操作进行阻塞或者失效, 表现就是页面卡顿或者无响应.

为了解决这个问题我们仍然可以使用虚拟滚动的方案或者懒加载的方案, 保证用户当前屏幕下的dom在一个合理的范围内, 如果是无法避免必须要展示大段dom元素, 我们可以用一个单独的页面来承载或者嵌入, 避免页面其他部分宕机. 也可以对复杂dom 进行局部“冷冻”(在非激活状态将其转化为图片, 激活时在逐渐渲染)

产品需求层优化

产品需求层面导致的重构主要场景比如:

  • 项目国际化支持
  • 项目埋点
  • 整体项目UI升级

当然还有很到场景这里不一一介绍了. 以上列的场景都是比较常见的, 而且也有很多解决方案, 后期我会一一复盘. 我们在项目重构之前或者立项之前, 这几种情况也是需要重点考虑的, 毕竟都是大工作量的任务

2. 技术升级带来的重构

技术升级带来的重构主要有前端框架的升级, 前端设计模式的升级, 脚手架的升级. 后面两个主要是围绕前端技术的不断演进, 我们采取的程序性升级, 比如从传统的 gulp 升级到 webpack, 或者从 webpack 升级到vite 等. 前者比较常见的场景是企业中有很多老的系统, 采用的是比较传统的技术方案如 CMD 模式 + jquery, 但是新项目采用的是 webpack + vue 或者 react, 此时我们需要更新项目情况来有选择的做重构:

老项目只需要少量维护的情况
这种情况我们就不需要大刀阔斧的重新用新框架再写一套了, 我们只需要在重构时, 对老项目代码做好足够的注释, 类库的封装即可:
在这里插入图片描述
其次我们需要做好js变量隔离, 因为传统模式我们会在 window 顶层定义大量 var 全局变量, 作为优化的一部分, 我们可以采用闭包自执行和变量约定来规范我的js变量定义, 以防止全局的变量污染.

老项目仍然需要不断迭代, 并且后期会有新的模块
这种情况我们需要做评估和拆分, 如果是小模块, 我们可以用 jquery插件 的方式快速爹迭代, 如果是页面级别的迭代, 并且交互比较复杂, 我们可以将老系统的新页面拆离一个子工程, 采用最新的框架(如vue)来开发迭代, 再通过 MPA 的方式和老系统做集成:
在这里插入图片描述

老项目和新项目需要相互通信, 嵌套
这种场景下最好的方式就是用iframe + postmessage, 或者我们可以参考类似微前端的方式来管理组织不同子系统.

组件库重构
在这里插入图片描述
对于一个包含很多子系统的复杂的项目系统来说,要想设计一个好的架构,第一步就是合理划分组件,组件的粒度拆成的足够细,这样才能最大限度的复用组件。

对于任何一个复杂系统来说,最重要的就是实现错综复杂的业务功能,但是不同模块或者子系统之间很多业务往往是相通的或者相似的,如果这个时候我们每个页面对于实现类似的业务场景都去重复去写一遍业务代码,那完全是没必要的,对于可维护性来说也是一种打击,所以基于这种场景我们的 业务组件 就很有必要出场了。我们可以把功能或者需求类似的有机体封装成一个业务组件,并对外暴露接口来实现灵活的可定制性,这样的话我们就可以再不同页面不同子系统中复用同样的逻辑和功能了。

同理,不同页面中往往有可能出现视觉或者交互完全相同或者类似的区块,为了提高可复用性和提高开发效率,我们往往会基于基础组件和业务组件再进行一次封装,让其成为一个独立的区块以便直接复用。

通过这样一层层封装,我们就逐渐搭建了一套完整的组件化系统,基于这种模式的开发往往也是一个好的前端架构的开始。但要注意一点就是高层次的组件一定会依赖低层次的组件,但是低层次的组件不可以包含高层次的组件。(听起来有点像rudex的单向数据流法则),他们的关系就好像下图:
在这里插入图片描述
所以对组件库的重构需要对我们的项目有一个本质的认知, 并对页面进行有效的拆分, 从而达到局部的最优, 降低后续的维护成本, 并能提高整个系统甚至跨系统的复用.
在这里插入图片描述

总结

系统重构是一个持续的过程, 我们不仅要有持续学习的态度, 还需要不断的实践和积累优秀的最佳实践, 这样才能在不断重构中让我们的系统不断适应复杂多变的“社会环境”.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/577047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

W5500-EVB-Pico评估版介绍

文章目录 1 概述2 板载资源2.1 硬件规格2.2 硬件规格2.3 工作条件 3 参考资料3.2 原理图3.3 尺寸图 (单位 : mm)3.4 参考例程 4 硬件协议栈优势 1 概述 W5500-EVB-Pico是基于树莓派RP2040和完全硬连线TCP/IP控制器W5500的微控制器开发板-基本上与树莓派Pico板相同,但…

【MATLAB库函数系列】线性调频Z(Chirp-Z,CZT)的MATLAB源码和C语言实现

在上一篇博客 【数字信号处理】线性调频Z(Chirp-Z,CZT)算法详解 已经详细介绍了CZT变换的应用背景和原理,先回顾一下: 回顾CZT算法 采用 FFT 算法可以很快计算出全部 N N N点 DFT 值,即Z变换 X ( z ) X(z) <

220v电源转换12v和24v用什么芯片

问&#xff1a;将220V电源转换为12V和24V - 使用什么芯片&#xff1f; 答&#xff1a;常用于将220V电源转换为12V和24V的芯片是AH8669和AH8665。 问&#xff1a;AH8669芯片提供了什么特点&#xff1f; 答&#xff1a;AH8669芯片适用于最大电流为700mA的应用。它内置了MOSFET…

01-黑马程序员大数据开发

一. Hadoop概述 1. 什么是大数据 &#xfeff;狭义上&#xff1a;对海量数据进行处理的软件技术体系&#xfeff;广义上&#xff1a;数字化、信息化时代的基础支撑&#xff0c;以数据为生活赋 2. 大数据的核心工作&#xff1a; &#xfeff;存储&#xff1a;妥善保存海量待…

5g消息-5G时代短信升级-富媒体智能交互-互联网新入口

在5G时代&#xff0c;运营商和各大手机厂商都在积极推进5G消息的商用&#xff0c;基于短信入口的富媒体消息应用在近两年得到快速发展&#xff0c;并在企业端形成了广泛应用。 作为5G时代的数字原生应用&#xff0c;5G消息支持用户通过文字、图片、音频、视频、位置等富媒体方式…

【算法题】链表重排(js)

力扣链接&#xff1a;https://leetcode.cn/problems/LGjMqU/description/ /*** Definition for singly-linked list.* function ListNode(val, next) {* this.val (valundefined ? 0 : val)* this.next (nextundefined ? null : next)* }*/ /*** param {ListNode…

C++11(上):新特性讲解

C11新特性讲解 前言1.列表初始化1.1{ }初始化1.2std::initializer_list 2.类型推导2.1 auto2.2 typeid2.3 decltype 3.范围for4.STL的变化4.1新容器4.2容器的新方法 5.右值引用和移动语义5.1 左值引用和右值引用5.2 左值引用与右值引用比较5.3 右值引用的使用场景5.4 右值、左值…

浙江大唐乌沙山电厂选择ZStack Cloud打造新一代云基础设施

浙江大唐乌沙山电厂选择云轴科技ZStack Cloud云平台为其提供高性能、高可用的云主机、云存储和云网络&#xff0c;构建了简单、稳定、安全、高效的云基础设施&#xff1b;通过ZStackCloud为其提供可视化服务编排、多租户自服务等模块&#xff0c;帮助电厂提高IT资源利用率&…

解决FTP传输慢的问题(ftp传输慢为什么)

在企业运营中&#xff0c;使用FTP进行文件或数据传输是相当普遍的做法。尽管FTP是一种传统的文件传输工具&#xff0c;但在实际应用中&#xff0c;我们可能会面临传输速度缓慢的问题&#xff0c;这不仅影响工作效率&#xff0c;还浪费时间。为了解决这一问题&#xff0c;我们可…

泛微OA xmlrpcServlet接口任意文件读取漏洞(CNVD-2022-43245)

CNVD-2022-43245 泛微e-cology XmlRpcServlet接口处存在任意文件读取漏洞&#xff0c;攻击者可利用漏洞获取敏感信息。 1.漏洞级别 中危 2.影响范围 e-office < 9.5 202201133.漏洞搜索 fofa 搜索 app"泛微-OA&#xff08;e-cology&#xff09;"4.漏洞复现 …

vue 项目/备案网页/ip网页打包成 apk 安装到平板/手机(含vue项目跨域代理打包成apk后无法访问接口的解决方案)

下载安装HBuilder X编辑器 https://www.dcloud.io/hbuilderx.html 新建 5APP 项目 打开 HBuilder X&#xff0c;新建项目 此处项目名以 ‘test’ 为例 含跨域代理的vue项目改造 若 vue 项目中含跨域代理&#xff0c;如 vue.config.js module.exports {publicPath: "./&…

【C++】开源:FTXUI终端界面库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍FTXUI终端界面库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c…

【文本处理】正则表达式

一、简介 正则表达式&#xff0c;又称规则表达式,&#xff08;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊字符&…

苹果发布了一个Ferret(雪貂)多模态大模型,在一个无人问津的角落被一位博主捞起来

苹果12月14日释放了一个名为Ferret的多模态大语言模型&#xff0c;有的翻译是雪貂&#xff0c;有的是法学硕士&#xff0c;要我说&#xff0c;还是叫雪貂吧&#xff0c;接地气亲民&#xff0c;将来犯蠢的时候出来发张雪貂的可爱表情包作公关就完事了&#xff0c;你个法学硕士到…

C语言—每日选择题—Day63

指针相关博客 打响指针的第一枪&#xff1a;指针家族-CSDN博客 深入理解&#xff1a;指针变量的解引用 与 加法运算-CSDN博客 第一题 1. 设C语言中&#xff0c;一个int型数据在内存中占2个字节&#xff0c;则unsigned int型数据的取值范围为 A&#xff1a;0~255 B&#xff1a;0…

mysql8.x版本_select语句源码跟踪

总结 源码基于8.0.34版本分析&#xff0c;函数执行流程含义大致如下&#xff1a; do_command 方法从连接中读取命令并执行&#xff0c;调用 dispatch_command 对命令进行分发。dispatch_command 调用 mysql_parse 对命令进行解析&#xff0c;如果遇到一条语句用 ; 分隔多条命…

CGAL中三角形曲面网格近似

1、介绍 此软件包实现了变分形状近似&#xff08;VSA&#xff09;方法&#xff0c;通过更简单的表面三角形网格来近似输入表面网格。该算法的输入必须是&#xff1a; 三角形分割&#xff1b;组合2流形 输出是一个三角形汤&#xff0c;可以构建成多边形曲面网格。 给定一个输入曲…

linux操作系统——进程(二) 进程状态

进程状态 你真正的理解了进程的状态嘛?特别是操作系统教材中学过的进程状态&#xff0c;你真的理解了吗&#xff1f; 教材上关于进程状态的说明 下面我们以下图为例: 这是教材上对操作系统的说明&#xff0c;但是它并没有详细的说明&#xff0c;这些状态具体是什么&#xf…

大语言模型说明书

在浩瀚的信息宇宙中&#xff0c;大语言模型如同一颗璀璨的星星正在熠熠生辉。21世纪以来&#xff0c;人工智能可谓是飞速发展&#xff0c;从简单的神经网络到大语言模型、生成式AI&#xff0c;这并非仅仅是一种技术的进步&#xff0c;更是人类智慧的飞跃。大语言模型不仅仅是语…

华为数通方向HCIP-DataCom H12-831题库(多选题:241-249)

第241题 (NEW) 以下哪些操作可能会影响客户网络的正常运行? A、从设备上下载日志 B、软件升级 C、路由协议配置变更 D、debug核心交换机上转发的所有IP报文 答案:ABCD 解析: 第242题 对于防火墙的默认安全区 Trust 和 Untrust 的说法,正确的有 A、从 Trust 区域访问 Untr…