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

BI 数据可视化平台建设(1)—交叉表组件演变实战

作者:vivo 互联网大数据团队 - Zhu Jianchen

本文是vivo互联网大数据团队《BI数据可视化平台建设》系列文章第1篇 - 交叉表组件。

交叉表在数据分析里应用广泛,通过本文,你将了解到:

  • 交叉表的基本概念,以及BI可视化平台常见术语。

  • 我们的表格类组件的演化过程,以及如何通过技术调研和优化实现大数据量下渲染性能,一步一步从原先的~10s降低到3~4s。

  • 交叉表的一些特定场景,提供了一些技术实现简易描述,对这些场景有一些宏观认识。

  • Worker,虚拟滚动,微应用等关键技术的实现细节。

一、背景

表格和表单在前端里面是最复杂的两类需求,在BI工具平台上,这2类组件需求更多,并且需要实现一些特有的交互展示。目前在敏捷BI平台上进行报表配置,表格类组件的使用占比达到了1/3,在可视化组件库里使用范围很广。为了满足不同的数据分析场景,表格组件主要分为分组表、交叉表、明细表三种类型,其中又以交叉表功能最为丰富强大。随着敏捷BI的业务的发展,交叉表组件也经历了多次设计改版以支持高性能的数据渲染和个性化的展示配置。本文主要通过交叉表组件的升级实践给大家讲解一下如何设计开发高性能的表格组件。 

术语注解

  • 【敏捷BI】

专为 vivo 生态用户量身打造的 自助式 BI 平台,提供从数据接入、数据准备、到数据分析、可视化应用、数据管理的一站式数据解决方案,同Quick BI,FineBI。

  • 【图表类型】

图表是数据视觉化表示的特殊方式。表示数据的方法有很多,如使用不同的符号、形状和排列,我们把这些称之为图表的类型。一些图表类型你比较熟悉,如条形图、饼图、折线图,但其他类型你可能就很少见了,如桑基图、树图、等值线图的地图。

  • 【交互方式】

交互式可视化允许您修改,操作和探索计算机显示的数据。绝大多数交互式可视化系统在计算机网络上,但越来越多出现在平板电脑和智能手机上。相比之下,静态可视化只显示单一的、非交互数据,它通常是为了打印和在屏幕上显示。

  • 【度量值】

表示数值的规模和范围。度量通常以间隔表示(10、20、30等等),代表度数字的单位,如价格、距离、年,或百分比。

  • 【指标】

同度量,表示具体某项值,单个值本身没有任何业务意义,一般需要对应的指标口径解释,才会具有业务价值。

二、交叉表介绍

交叉表(Cross Tabulations)是一种常用的由 行、列、汇总字段 三个元素组成分类汇总表格。利用交叉表查询数据非常直观明了,在进行数据分析中也被广泛应用。这里牵涉到另外一个概念即分组报表,分组报表是所有报表当中最普通,最常见的报表类型,也是所有报表工具都支持的一种报表格式。从一般概念上来讲,分组报表就是只有纵向的分组,传统的分组报表制作方式是把报表划分为条带状,用户根据一个数据绑定向导指定分组,汇总字段,生成标准的分组报表。交叉表有多列查询能力、分类汇总、多角度排序、交互式分析等特性。

图片

三、架构演变历程

为了提高交叉表的数据渲染性能和功能扩展能力,敏捷BI的表格组件经历了三次的设计升级。最开始用的jQuery拼接表格方式实现,随着组件化方案的推行,采用了组件化的方式实现升级,随着业务的发展,用多维度、多指标交叉分析场景越来越多了,尤其是通过交叉表进行分析时,大数据量出现了渲染崩溃等问题,所以我们最后通过微前端方式实现。  下面我们从开发难度,性能,功能扩展性,学习成本等方面的调研来讲解对底层表格的升级实践。

图片

3.1 V1版表格

敏捷BI平台第一版表格,技术栈是基于jQuery+DIV的方式实现的。表格拼接属于jQuery时代的常见开发风格,这种方式,代码可维护性会非常差,很容易会出现标签不匹配的情况,不带缩进,调试起来也比较费劲。这个版本的表格组件支持的业务场景主要是数据的基本展现,无法满足用户对表格的数据分析的需求。

  • 架构设计

图片

// 简单的拼接代码demo
function createTable() {var data = new Array();data.push('<table border=1><tbody>');for (var i = 0; i < 2000; i++) {data.push('<tr>');for (var j = 0; j < 5; j++) {data.push('<td>' + i + ',' + j + '</td>');}data.push('</tr>');}data.push('</tbody><table>');document.getElementById('table1').innerHTML = data.join('');}

3.2 V2版表格

随着系统整体架构升级,前后端分离的推进,我们从原生的table组件迁移到Vue组件化上,开发了V2版表格组件。  平台的整体架构全面迁移到vue+ant-design-vue上面。

1. 功能拓展

鉴于ant-design-vue上正好有table组件,对此我们对比了antd的table组件和element的table组件。2 种表格对比来看,ant-design-vue参照ant.design的React版开发出来,配置相对element更丰富,考虑到本身复杂场景支持性,更适合深度定制,最终选择了ant.design的vue版本。

图片

V2版的表格主要支持这几类场景配置(条件格式,合计行/列,单元格/行样式/内容定制等):

业务场景&具体实现

(1)数据展示

整体就是根据不同情况设置不同的column的字段,另外为了达到点击交互下,能够获取业务的数据,需要在column上挂一些冗余数据,这样会让column的数据信息很庞大。

columns是一个tree结构,这里采用的是dfs遍历,depth标识层级,item, itemType就是冗余的数据信息,在处理业务的时候会用到。

图片

图片

(2)数据排序

图片

(3)数据过滤

(4)单元格自定义渲染

图片

(5)多级表头定制

这个实现难点主要在于把已有的列如何放到新增的表头里,保持树形children结构具体实现代码也比较复杂,总共80行。

图片

图片

(6)条件格式渲染(条形图,热力图)

根据设定的条件,定制表格内单元格内容的样式

图片

(7)合计行/列配置

添加合计列和行,内置min,max,avg,sum表达式,支持自定义简易字段表达式运算这个功能难点在于合计列与行交叉的场景,也就是如何计算合计列的合计行。

图片

2. 架构设计

图片

3. 渲染优化

这个阶段的交叉表,在功能上已经能够满足绝大多数分析场景,但是一些数据量大的表格反馈渲染白屏时间过长,经常会出现浏览器崩溃,表格的性能面临新的挑战。另外表格在渲染时,CPU会占满,导致其他图表也会卡住等待,形成假死的现象。我们通过分析大数据表格渲染流程,发现有30%的时间会花销在数据适配,因此我们思考能不能把数据计算部分隔离出来,计算的时候,不阻塞渲染主进程,这样的话,浏览器渲染就可以处理其他的渲染任务。在做性能优化调研时,我们引入了service worker,worker在处理cpu密集型任务有独特的优势,所以我们把数据预处理的过程交给了Worker。之前没有使用worker时,我们前端逻辑会处理很多数据初始化和计算的操作,对于一个数据量很大的表格,会导致渲染卡顿2~3s,有些个别情况会导致浏览器崩溃的现象。

Worker原理和定义

W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存。service worker是浏览器的一个高级特性,本质是一个web worker,是独立于网页运行的脚本。

web worker这个api被造出来时,就是为了解放主线程。因为,浏览器中的JavaScript都是运行在单一个线程上,随着web业务变得越来越复杂,js中耗时间、耗资源的运算过程则会导致各种程度的性能问题。

而web worker由于独立于主线程,则可以将一些复杂的逻辑交由它来去做,完成后再通过postMessage的方法告诉主线程。service worker则是web worker的升级版本,相较于后者,前者拥有了持久离线缓存的能力。

3.3 V3版表格

在开发V2表格时,我们意识到数据处理部分不应该交给前端,列拼接上掺杂了太多的业务场景处理,另外渲染性能和崩溃问题急需解决,对此我们进行了V3版本迭代,提前对表格版本进行了技术升级,为之后的新一批列汇总行汇总,分组小计等高级交叉分析需求做好技术储备。

1. 技术选型

我们对比了react,vue及canvas生态有代表性的表格组件。综合三者优劣势最终确定了基于react的table组件。

图片

S2:https://github.com/antvis/S2

ali-react-table:https://github.com/alibaba/ali-react-table

vxe-table:https://github.com/x-extends/vxe-table/tree/v2

vxe-table设计初衷是解决单元格编辑的问题,主要用于大量增删改查的场景,性能不是它唯一的目标;S2是建立在电子表格需求上的,对筛选、排序、搜索、复制、框选、聚合分析都有诉求。

同时需要在大数据量下保持高性能,解决之前商业软件版本实现的性能问题和拓展性问题,所以它覆盖的场景更全更复杂,但是它的缺点就是定制型不强,不太适合我们自身的业务。

所以最终我们选择了ali-react-table,它本身体积小,在基础能力都满足的情况下,扩展新功能也很容易,而且在大数据量渲染下有高性能的优势。

2. 架构设计

后端接口返回数据和配置部分,基于渲染模型:左树 + 上树 => 表格,根据配置生成左树leftTree和上树topTree,构造数据源,参照了ant-design的Table组件数据源构造的流程,与自身的pipeline插件机制结合,实现了表格的交互操作(排序,筛选,分页)。

由于本项目里接入了微前端架构,采用了loadApp的方式实现了异构应用混合开发:

图片

运作流程图如下:

图片

3. 升级实践

(1)架构升级:

图片

(2)底层渲染:

虚拟滚动:长列表渲染受制于浏览器本身限制,在大量DOM下,会达到浏览器本身的渲染瓶颈,在这种情况下,虚拟滚动可以解决这种渲染问题,它是一种按需渲染的理念的体现。所以虚拟列表是一种根据滚动容器元素的可视区域来渲染长列表数据中某一个部分数据的技术。

大致原理如下图:

图片

我们发现长列表在展示时,用户只会关注可视区域,其他非可视区域部分,我们可以把已经渲染的DOM销毁,不需要立即渲染的DOM延后。所以优化策略就是只渲染可见区域的内容。

在滚动事件触发后,根据滚动 Offset 调整相应渲染的内容即可。在用户看来,还是一个完整的长列表。这种懒加载的方式,和早期页面图片资源懒加载和非必须资源异步加载属于同一种思路。

在新版版本里,ali-react-table自带了虚拟滚动的特性,在大列表下,框架会自动开启,可以明显提升表格渲染性能和滚动的性能。

四、同类产品对比

4.1 技术架构对比

1. Quick BI

① 架构设计

图片

② 技术实现

  • 使用原生div和flex布局,不使用原生table表格

  • 列宽,固定列,固定表头等表格不好实现的问题,都易实现,渲染性能也较好

  • 有2个版本的表格,旧版表格使用table,在这种情况下,性能,复杂交互,分组都存在瓶颈,这一点和我们类似,新老版本的表格同时在线上应用

  • 虚拟滚动支持横向,纵向滚动

③ 优劣势

  • ali-react-table不维护了,源码不太复杂,可以二次迭代开发;基本满足交叉表所有功能;大数据量下渲染高性能

  • 接口数据略冗余

④ 备注

  • 数据结构明确行维、列维、指标列数据;

  • 数据汇总和小计是存放在后端

2. 敏捷BI

① 架构设计

图片

② 技术实现

  • 使用table布局

  • 使用position:sticky实现固定列;固定表头使用独立的单表头表格模拟,这里需要强制table设置列宽,保证列对齐

  • 支持横向,纵向虚拟滚动,在10w列下依然可以正常渲染

  • 在ali-react-table基础上扩展了按维度合并,表头筛选等feature

③ 优劣势

  • flex布局灵活,不受表格本身布局限制,易实现固定列和表头,列宽;canvas开发成本较高,bug不好调试

  • 接口数据更精简

④ 备注

  • 数据结构不明确,需要对二维数组转换,存在一定的预处理逻辑;

  • 数据结构存在冗余现象

4.2 应用场景对比

以实际测试为准

1. Quick BI

业务场景

(1)字段配置

  • 行:数据集的维度字段拖拽到行选择区

  • 列:数据集里的维度或者度量字段拖拽到列选择区

  • 过滤器:数据集字段拖拽到过滤器选择区,对字段进行筛选

(2)样式配置

  • 标题与卡片:设置标题样式

  • 备注和尾注:设置图表备注和尾注内容

  • 组件容器:设置内边距和背景色,圆角

  • 展示型配置:设置主题,表头样式,内容样式,冻结列,序号等配置

  • 功能型配置:条件格式配置,针对字段满足特定条件下突出显示配置的样式

  • 总计配置:支持列汇总和行汇总,行总计和行小计,列总计和列小计

(3)高级配置

  • 联动:图表里的字段与其他图标关联

  • 跳转:图表字段跳转传值

 技术实现

  • 实现使用原生,未使用第三方库

  • 自定义主题使用主色编辑

  • 拖拽方式交互

2. 网易有数

业务场景

  • 没有复杂的交叉表场景,只支持普通明细表

  • 配置方式主要包括主题,表头,内容的字体样式,背景,对齐等样式

  • 支持下钻,字段跳转

  • 数据集字段支持维度层级和组的概念

  • 没有虚拟滚动

 技术实现

  • 内部使用table表格实现

  • 主题配置支持上传主题json文件

3. 敏捷BI

(1)字段配置

  • 行维:数据集维度字段放置区

  • 列维:数据集维度字段放置区

  • 指标:数据集指标字段

(2)图表属性和图表样式配置

  • 支持条件格式,自定义代码样式嵌入,主题配置

(3)字段过滤

  • 使用字段过滤数据

 技术实现

  • 最开始使用smooth-dnd库,来实现从数据集字段拖拽到行列、指标区

  • 因为smooth-dnd有性能问题,不再维护等问题,就废弃掉了,使用原生的拖拽实现

  • 主题使用在线代码编辑主题,基于codemirror在线代码,接入css variables,实时应用,不需要刷新

4.3 部分核心代码实现

应用场景① :表头筛选

代码实现:

图片

应用场景②:按维度合并

代码实现:

图片

4.4 渲染性能对比

1. Quick BI

(1)数据量级 <50列

  • 接口耗时300ms 接口大小<5kb

  • 渲染耗时 < 1s

注:数据量不是很大的情况下,数据加载忽略不计,合入到数据渲染时间,差别不大

(2)数据量级 ≥ 200列

  • 接口耗时1.88s 接口大小<10kb

  • 表格渲染 < 3s

注:数据量很大的情况下,数据加载需要单独计入时间

(3)数据量级 > 1W列

极端情况下,表格渲染崩溃

图片

2. 敏捷BI

(1)数据量级 <50列

  • 接口耗时250ms 接口大小~100kb

  • 渲染耗时 < 1s

(2)数据量级 ≥ 200列

  • 接口耗时300ms 接口大小~300kb

  • 渲染耗时 <3s

(3)数据量级 > 1W列

  • 接口耗时2s 数据大小2M

  • 渲染耗时~10s

4.5 总结

网易有数表格组件较为简单,只有简单的数据展示和排序筛选,适用于明细数据展示场景。

Quick BI表格和敏捷BI在交互,可视化能力,业务场景上都保持着同样的功能,底层实现 Quick BI采用原生DIV+Flex布局模拟表格实现,在渲染上比表格会有渲染的优势,这点是浏览器自身渲染机制决定,我们内部实现需要满足极端数据量下数据展示,所以特定做了横向的虚拟列表优化,这种场景看业务需求,否则表格会过于复杂,得不偿失。

表格渲染性能基本与Quick BI性能相当,极端情况下,敏捷BI依旧可以正常渲染,这点优于Quick BI。

五、规划

  • 数据预处理部分不由前端处理,交给后端,和后端协调好返回的数据结构,直接返回;

  • 表格扩展的功能与表格耦合严重,表格渲染不够纯净;

  • 开发一个Headless UI,不依赖渲染框架,提供一个数据适配层,同时支持在Vue3生态上使用。

参考资料:

  1. ali-react-table 站在巨人肩上,可惜不维护了

  2. ant-design table组件源码实现

相关文章:

BI 数据可视化平台建设(1)—交叉表组件演变实战

作者&#xff1a;vivo 互联网大数据团队 - Zhu Jianchen 本文是vivo互联网大数据团队《BI数据可视化平台建设》系列文章第1篇 - 交叉表组件。 交叉表在数据分析里应用广泛&#xff0c;通过本文&#xff0c;你将了解到&#xff1a; 交叉表的基本概念&#xff0c;以及BI可视化平…...

Python---练习:求幸运数字6

案例&#xff1a; 幸运数字6&#xff08;只要是6的倍数&#xff09;&#xff1a;输入任意数字&#xff0c;如数字8&#xff0c;生成nums列表&#xff0c;元素值为1~8&#xff0c;从中选取幸运数字移动到新列表lucky&#xff0c;打印nums与lucky。 思考&#xff1a; 要求是6的…...

【云栖2023】王峰:开源大数据平台3.0技术解读

本文根据2023云栖大会演讲实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;王峰 | 阿里云研究员&#xff0c;阿里云计算平台事业部开源大数据平台负责人 演讲主题&#xff1a;开源大数据平台3.0技术解读 实时化与Serverless是开源大数据3.0时代的必然选…...

如何改变Wi-Fi的IP地址,提高网络连接稳定性和速度

Wi-Fi已经成为我们日常生活中必不可少的一部分。大多数家庭和办公室都依赖于Wi-Fi来连接网络和进行各种在线活动。然而&#xff0c;有时我们可能会遇到网络连接不稳定或速度较慢的问题。这可能是由于IP地址的设置不当所导致的。虎观代理小二二将向您介绍如何改变Wi-Fi的IP地址&…...

APP 备案公钥、签名 MD5、SHA-1、SHA-256获取方法。

公钥和 MD5 值可以通过安卓开发工具、Keytool、Jadx-GUI 等多种工具获取&#xff0c;最简单的就是以 appuploader为例。 1.下载 appuploader工具 &#xff0c;点击此处 下载 appuploader 工具。 2.下载完成后&#xff0c;解压压缩包&#xff0c;双击 appuploder 运行。 3.运…...

屏幕提词软件Presentation Prompter mac中文版使用方法

Presentation Prompter for mac是一款屏幕提词器软件&#xff0c;它可以将您的Mac电脑快速变成提词器&#xff0c;支持编写或导入&#xff0c;可以在一个或多个屏幕上平滑地滚动&#xff0c;Presentation Prompter 下载是为适用于现场表演者&#xff0c;新闻广播员&#xff0c;…...

Rc与Arc实现1vN所有权机制

Rc与Arc实现1vN所有权机制 观察引用计数的变化一个例子多线程无力的Rc< T >Arc Rust所有权机制要求一个值只能有一个所有者&#xff0c;在大多数情况下&#xff0c;都没有问题&#xff0c;但是考虑以下情况&#xff1a; 在图数据结构中&#xff0c;多个边可能会拥有同一个…...

建造者模式 rust和java的实现

文章目录 建造者模式介绍优点缺点使用场景 实现javarust rust代码仓库 建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 介绍…...

书写Prompt的经验总结

首先最重要的一点是Prompt无法全部模型都通用&#xff0c;可能你的Prompt在ChatGPT中使用很好&#xff0c;迁移到ChatGLM就不行了。不知道未来是否会出现Prompt的跨平台。 首先书写Prompt要明确告诉模型要做什么&#xff0c;而不是告诉它不要做什么。还要保证精简&#xff0c;…...

WebSocket实时应用

在开发一些前端页面的时候&#xff0c;总是能接收到这样的需求&#xff1a;如何保持页面并实现自动更新数据呢&#xff1f;以往的常规做法&#xff0c;是前端使用定时轮询后端接口&#xff0c;获取响应后重新渲染前端页面&#xff0c;这种做法虽然能达到类似的效果&#xff0c;…...

从零开始搭建React+TypeScript+webpack开发环境-基于lerna的webpack项目工程化改造

项目背景 在实际项目中&#xff0c;我们的前端项目往往是一个大型的Webpack项目&#xff0c;结构较为复杂。项目根目录下包含了各种配置文件、源代码、以及静态资源&#xff0c;整体布局相对扁平。Webpack的配置文件分散在不同的部分&#xff0c;包括入口文件、输出目录、加载…...

网络监控系统和防火墙的区别有哪些?

现如今&#xff0c;市面上保护企业网络安全的设备有很多&#xff0c;其中使用最多的当属网络监控系统和防火墙。 网络监控系统就是通过网页内容的自动采集处理、敏感词过滤、智能聚类分类、主题检测、专题聚焦、统计分析等多个环节&#xff0c;实现相关网络舆情监督管理的需要…...

刷题学习记录BUUCTF

[极客大挑战 2019]RCE ME1 进入环境直接就有代码 <?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]/",$code)){die("NO.");}eval($co…...

Linux imu6ull驱动- led

一、GPIO模块结构 开始来啃手册了&#xff0c;打开我们的imx6ull手册。本章我们编写的是GPIO的&#xff0c;打开手册的第28章&#xff0c;这一章就有关于IMX6ULL 的 GPIO 模块结构。 mx6ull一共有5 组 GPIO&#xff08;GPIO1&#xff5e;GPIO5&#xff09; GPIO1 有 32 个引脚&…...

【 云原生 | K8S 】Kubernetes 概述

Kubernetes 概述 1 K8S 是什么&#xff1f; K8S 的全称为 Kubernetes (K12345678S)&#xff0c;PS&#xff1a;“嘛&#xff0c;写全称也太累了吧&#xff0c;不如整个缩写”。 作用&#xff1a; 用于自动部署、扩展和管理“容器化&#xff08;containerized&#xff09;应用…...

边缘计算多角色智能计量插座:用电监测和资产管理的未来智能化引擎

目前主流的智能插座涵盖了红外遥控&#xff08;控制空调和电视等带有红外标准的电器&#xff09;&#xff0c;配备着测温、测湿等仓库应用场景&#xff0c;配备了人体红外或者毫米波雷达作为联动控制&#xff0c;但是大家有没有思考一个问题&#xff0c;就是随着对接的深入&…...

mysql隐式转换转换引起的bug

生产环境中遇到一个情况情况 &#xff0c;过滤数据发现过滤不掉相关值情况&#xff0c;具体情况如下 原始数据&#xff1a; CREATE TABLE test (id bigint(11) NOT NULL AUTO_INCREMENT COMMENT 自增id,subject_id bigint(11) NOT NULL DEFAULT 0 COMMENT 主题id,subject_nam…...

【Python】gevent模块实现协程模拟高并发

Python中GIL的存在&#xff0c;导致多线程一直不是很好用&#xff0c;相形之下&#xff0c;协程的优势就更加突出了。 Python通过yield提供了对协程的基本支持&#xff0c;但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。 gevent是第三方库&#xff0c;通过gr…...

leetcode:2485. 找出中枢整数(python3解法)

难度&#xff1a;简单 给你一个正整数 n &#xff0c;找出满足下述条件的 中枢整数 x &#xff1a; 1 和 x 之间的所有元素之和等于 x 和 n 之间所有元素之和。 返回中枢整数 x 。如果不存在中枢整数&#xff0c;则返回 -1 。题目保证对于给定的输入&#xff0c;至多存在一个中…...

asp.net core mvc之模型绑定、特性约束模型绑定、模型验证(服务器/客户端/远程)

一、不用模型绑定 数据类型都是string 1、UserController.cs public class UserController : Controller {public IActionResult Register(){return View();}[HttpPost]public IActionResult DoRegister(){//不用模型绑定 以前的方法取表单数据或Url的参数//数据类型都是s…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...