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

news2025/2/8 23:44:23

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

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

技术因素

  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.coloradmin.cn/o/1335969.html

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

相关文章

【http】缓存协议

✨ 专栏介绍 在当今互联网时代,计算机网络已经成为了人们生活和工作中不可或缺的一部分。而要实现计算机之间的通信和数据传输,就需要依靠各种网络协议来进行规范和约束。无论是浏览网页、发送电子邮件还是进行在线交流,都离不开各种各样的网…

使用pytorch神经网络拟合计算模型

一. 内容简介 python调用百度翻译api,将中文论文翻译英文,并保留部分格式 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3数据文件 链接:https://pan.baidu.com/s/1csJOoErGyx77MW_FImVKjg?pwd1234 三.主要流程 3.…

@click 默认传递原生的事件对象

项目场景 [Day1] <template><div id"app"><h1>小黑记事本</h1><button click"handleClick">www</button><div class"head"><!-- 按键&#xff08;回车&#xff09;按下&#xff0c;出发add事件&…

MyBatis见解4

10.MyBatis的动态SQL 10.5.trim标签 trim标签可以代替where标签、set标签 mapper //修改public void updateByUser2(User user);<update id"updateByUser2" parameterType"User">update user<!-- 增加SET前缀&#xff0c;忽略&#xff0c;后缀…

uniapp创建/运行/发布项目

1、产生背景----跨平台应用框架 在移动端各大App盛行的时代&#xff0c;App之间的竞争也更加激烈&#xff0c;他们执着于让一个应用可以做多个事情 所以就应运而生了小程序&#xff0c;微信小程序、支付宝小程序、抖音小程序等等基于App本身的内嵌类程序。 但是各大App他不可…

解决ELement-UI三级联动数据不回显

目录 一.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式。 二.检查数据格式是否正确 三.绑定v-if 确保每次执行 四.完整代码 一.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式。 二.检查数据格式是否正确…

通过three.js玩转车展项目

1.项目搭建 1.1 创建文件夹 mkdir 文件名1.2 初始化package.json npm init -y1.3 安装打包工具并配置相关依赖 npm i parcel -d在package.json中打包路径和指令 1.4 安装three.js npm i three -d2.项目搭建 2.1 新建index.html&#xff0c;并再index.html引入car.js,在…

分类预测 | Matlab实现SCSO-SVM基于沙猫群优化算法优化支持向量机的多变量分类预测【23年新算法】

分类预测 | Matlab实现SCSO-SVM基于沙猫群优化算法优化支持向量机的多变量分类预测【23年新算法】 目录 分类预测 | Matlab实现SCSO-SVM基于沙猫群优化算法优化支持向量机的多变量分类预测【23年新算法】分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现SCSO-…

MySQL递归公用表表达式

&#x1f607;作者介绍&#xff1a;一个有梦想、有理想、有目标的&#xff0c;且渴望能够学有所成的追梦人。 &#x1f386;学习格言&#xff1a;不读书的人,思想就会停止。——狄德罗 ⛪️个人主页&#xff1a;进入博主主页 &#x1f5fc;专栏系列&#xff1a;MySQL知识 &…

asp.net core 教程

asp.net core 教程 写在前面新建项目Get和PostGETPOST MVC-模型控制视图如何通俗理解MVC代码实例 API模型&#xff08;前后端分离&#xff09;前端代码后端代码 文件配置优先级优先级顺序 从数据库读取配置文件数据缓存 写在前面 学了快一年多的C#了&#xff01; 我最开始学的…

XxlJob 常见的报错

XxlJob 启动日志报错&#xff1a; 报错一&#xff1a; ERROR c.x.job.core.util.XxlJobRemotingUtil - Connection refused: connect java.net.ConnectException: Connection refused: connect 解决方法&#xff1a; 要启动的类是 XxlJobAdminApplication &#xff0c;而不是…

【论文阅读】MCANet: Medical Image Segmentation with Multi-Scale Cross-Axis Attention

文章目录 摘要创新点总结实现效果总结 摘要 链接&#xff1a;https://arxiv.org/abs/2312.08866 医学图像分割是医学图像处理和计算机视觉领域的关键挑战之一。由于病变区域或器官的大小和形状各异&#xff0c;有效地捕捉多尺度信息和建立像素间的长距离依赖性至关重要。本文提…

SpringBoot Event,事件驱动轻松实现业务解耦

什么是事件驱动 Spring 官方文档AWS Event Driven 简单来说事件驱动是一种行为型设计模式&#xff0c;通过建立一对多的依赖关系&#xff0c;使得当一个对象的状态发生变化时&#xff0c;所有依赖它的对象都能自动接收通知并更新。即将自身耦合的行为进行拆分&#xff0c;使拆…

vscode括号颜色突然变成白色的了,怎么解决

更新版本后发现vscode的各种括号都变成了白色&#xff0c;由于分色括号已经使用习惯&#xff0c;突然变成白色非常不舒服&#xff0c;尝试多次后&#xff0c;为大家提供一下几种解决方式&#xff0c;希望能帮到同样受到此种困惑的你&#xff1a; 第一种&#xff1a; 首先打开…

TYN-02A-Ⅱ 太阳能警示灯

应用范围: 可安装在电线杆&#xff0c;路灯&#xff0c;围挡&#xff0c;交 通护栏及各种杆式固体等场所起警示作用。 产品特点&#xff1a; 采用进口PS材质; 光控无开关&#xff0c;白天不闪&#xff0c;昏暗环境自动闪烁&#xff0c;无需手动操作&#xff0c;省时省事; …

blender使用faceit绑定自己的表情动作

blender使用faceit绑定自己的表情控制模型 faceit是个神器&#xff0c;来记录一下如何让表情动起来保持相对位置头部分离&#xff0c;方便后续绑定faceitfaceit的注册rig生成地标Animate可以修正表情烘培之前记得保存使用Faceit的整个流程 faceit是个神器&#xff0c;来记录一下…

test-03-java 单元测试框架 testNG 入门介绍 junit/junit5/testNG 详细对比

拓展阅读 test-01-java 单元测试框架 junit 入门介绍 test-02-java 单元测试框架 junit5 入门介绍 test-03-java 单元测试框架 testNG 入门介绍 junit/junit5/testNG 详细对比 test assert-01-Google Truth 断言 test 系统学习-03-TestNG Spock testng 入门使用教程 开源…

Oracle 学习(2)

过滤和排序数据 where条件过滤 日期格式 查询10号部门的员工信息&#xff1a;SQL> select * from emp where deptno10 查询”KING”的信息&#xff1a;SQL> select * from emp where ename KiNg 未选定行。 注意&#xff1a;字符串大小写敏感。 SQL> selec…

【论文笔记】3D Gaussian Splatting for Real-Time Radiance Field Rendering

原文链接&#xff1a;https://arxiv.org/abs/2308.04079 1. 引言 网孔和点是最常见的3D场景表达&#xff0c;因其是显式的且适合基于GPU/CUDA的快速栅格化。神经辐射场&#xff08;NeRF&#xff09;则建立连续的场景表达便于优化&#xff0c;但渲染时的随机采样耗时且引入噪声…

时序预测 | Matlab实现SSA-CNN-BiLSTM麻雀算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | Matlab实现SSA-CNN-BiLSTM麻雀算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现SSA-CNN-BiLSTM麻雀算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN-BiLSTM麻雀算…