跨端跨栈连载 5/7:如何借助 Taro Next 横穿跨端业务线
2020/7/22 11:03:49
本文主要是介绍跨端跨栈连载 5/7:如何借助 Taro Next 横穿跨端业务线,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前端早早聊大会,前端成长的新起点,与掘金联合举办。 加微信 codingdreamer 进大会专属小程序群。
第十三届|前端构建专场,8-15 直播,8 位讲师(蚂蚁金服/淘宝等),大会报名地址
本文是第十届 - 前端早早聊第 67 场,来自京东 Taro 团队的 JJ 分享讲稿简要整理版(完整版含演示请看录播视频和 PPT):
![](/upload/202007/22/202007221103389742.png)
大家下午好,我是来自京东凹凸实验室的陈嘉健,今天我的分享主题是如何借助 Taro Next 横穿跨端业务线。
前言、Taro框架
![](/upload/202007/22/202007221103392993.png)
Taro 是一款开源的多端统一开发框架,它让我们只编写一份代码,就可以让这份程序运行在各个小程序端、H5端、RN端,在开源两年多以来收获了业界的很多关注,然后现在在 github 上面的 Star 数有 25,000 多,同时业界也有非常多的团队正在使用 Taro 框架进行开发。那么在过去的一年里面,我们谋划着一个比较大的重构,也就是我今天将要分享的 Taro Next。
![](/upload/202007/22/202007221103394692.png)
一、Taro Next 背景
首先来介绍一下为什么我们要重构,主要有两个原因,第一个是为了解决目前架构上面的一些缺陷,第二个是希望新增对于多个框架的支持。
![](/upload/202007/22/202007221103395903.png)
1.1、Taro 架构
![](/upload/202007/22/202007221103397377.png)
首先来看一下目前 Taro 的整体架构,它分为两个部分,第一部分是编译时,第二部分是运行时。编译时会先对用户的 React 代码进行编译,转换成各个端上的小程序都可以运行的代码,然后再在各个小程序端上面都配上一个对应的运行时框架进行适配,最终让这份代码运行在各个小程序端上面。那么这个架构有什么问题呢?
1.2、Taro 编译时缺陷
![](/upload/202007/22/202007221103398920.png)
首先看一下编译的实现过程:编译时是借助 babel 去对源代码进行词法、语法分析、语义分析,得出一棵抽象语法树 AST,然后对这棵抽象语法树进行一些转换操作,最终得出目标代码。这样的实现过程共有三大缺点:
- JSX 支持程度不完美。Taro 对 JSX 的支持是通过编译时的适配去实现的,但 JSX 又非常之灵活,因此还不能做到100%支持所有的 JSX 语法。
- 不支持 source-map。Taro对源代码进行了一系列的转换操作之后,就不支持 source-map了,用户调试、使用这个项目就会不方便。
- 维护和迭代十分困难。Taro 编译时代码非常的复杂且离散,维护迭代都非常的困难。
1.3、Taro 运行时缺陷
![](/upload/202007/22/202007221103400785.png)
接下来再看一下运行时的缺陷。现在对于每个小程序平台,我们都会提供对应的一份运行时框架进行适配。当我们修改一些 Bug 或者新增一些特性的时候,需要我们同时去修改多份运行时框架,这显然是不合理的。
1.4、希望支持更多框架
![](/upload/202007/22/202007221103402611.png)
另一方面我们也希望去支持更多的框架。目前 Taro 只支持 React,但是公司内部也有很多使用 Vue 技术栈的团队,她们也希望享受到 Taro 编译到多端的能力,因此我们就想能不能去支持 Vue,甚至 jQuery、Angular 等框架。
二、Taro Next 新特性
![](/upload/202007/22/202007221103404358.png)
说完重构 Taro 的原因之后,我们再来说说 Taro 重构之后 Taro Next 的新特性。
2.1、Taro Next 架构
![](/upload/202007/22/202007221103406331.png)
这是Taro Next 的整体架构图,即使各个 Framework 的框架拥有不同的组件库、生命周期、API,但我们仍然可以选定微信小程序作为一个基准,然后使用各种框架,去对接微信小程序的组件库、生命周期、API,然后在 Taro 运行时,内部对各个平台的缺失部分进行补全。例如在小程序里面,它没有 DOM 和 BOM,那我们就去实现对应的DOM 和 BOM,然后在 H5 端并没有微信小程序规范的组件库、路由规范、API 等等,我们也要去实现,最后用 Webpack 去对运行时的代码进行打包,就可以让整份代码运行在不同的平台上面。
2.2、Taro Next 优点一
![](/upload/202007/22/202007221103408547.png)
整体来说 Taro Next 有三个优点。第一点是 Taro Next 更强大了,我们现在不限制语言和语法,可以运行各种真实的框架,还提供了渲染 HTML 和跨框架组件这些比较特色的功能。
2.3、Taro Next 优点二
![](/upload/202007/22/202007221103410881.png)
第二点是 Taro Next 更迅速了。我们剥除了 AST 操作,让构建速度更快。其次,我们也提升了项目初始化、更新操作的性能。除了Taro 自身的优化外,我们还提供了一系列的优化选项给用户,让用户可以根据自己的实际情况对项目进行调用。
2.4、Taro Next 优点三
![image.png](/upload/202007/22/202007221103414640.png)
第三点是更灵活了,我们现在提供了一个插件化的系统,用户可以根据自己的场景去拓展一些自己的能力。然后我们还把一些 Taro 的内部配置项、Webpack 的配置项给暴露出来,用户可以配置的项目就更加之多。其次对 Taro 的依赖做了瘦身,现在 Taro 用户可以根据自己的实际情况去安装对应的依赖,而不是像以前一样把所有的依赖都打包到 Taro 的 cli 里面。
三、开发实践
![](/upload/202007/22/202007221103416427.png)
看完 Taro Next 新特性之后,再了解一下怎么样去使用 Taro 进行开发。
![](/upload/202007/22/202007221103417784.png)
这一部分会分为5个小节,首先是开发前的一些准备工作,然后是开始编码,项目进阶,多端开发,还有性能优化。
3.1、准备工作
![](/upload/202007/22/202007221103419004.png)
先来看一下我们开发之前要做一些什么样的准备工作。
3.1.1、环境准备
![](/upload/202007/22/202007221103420410.png)
首先我们需要安装 Taro 的 CLI 工具。这里分两种情况,如果是要新建一个项目的话,可以使用 init 命令去新建一个全新的项目;如果用户自己本来就有一个微信小程序项目的话,我们也提供了 convert 命令,让用户可以把自己的微信小程序项目给转换到 Taro 项目中来,得到 Taro 项目之后,可以运行 build 命令,然后把 Taro 项目运行到各个端上面。
3.1.2、项目配置准备
![](/upload/202007/22/202007221103422402.png)
在开始编码之前,我们首先需要去对 Taro 进行一些配置。Taro 有一个配置文件,按区域划分,可分为公共配置、小程序配置、H5 配置。按种类划分,它就分为 Taro 内部配置项和 Webpack 相关的配置项。
3.1.3、babel配置准备
![](/upload/202007/22/202007221103424297.png)
接下来看一下对于 babel 的配置,目前 Taro 框架的 babel 配置是放在刚刚我们说的 Taro 配置里面的,但在 Taro Next 我们升级了 babel7,因此用户可以直接使用 babel 的配置文件 babel.config.js 进行配置,配置文件里面默认会带有 Taro 的 preset,他有个比赛里面会有一些常用的 presets 和 plugins,比如 @babel/preset-env、@babel/plugin-transform-runtime 等等。然后如果用户在使用 react 或者 typescript 时,也会去加入对应的 presets。
3.1.4、App、Page 配置准备
![](/upload/202007/22/202007221103425859.png)
接下来看一下 App 和 Page 配置。和小程序相对应, Taro 里面也有一个入口配置文件 app.config.js,每个页面也会有自己对应的配置,但和小程序、目前的 Taro 只能写 json 形式的配置不一样的是,Tarol Next 使用了@babel/register 去加载这些配置文件,因此用户可以使用 ES Next 的语法去编写这些配置,使用起来就会更加灵活。
3.2、开始编码
![](/upload/202007/22/202007221103427128.png)
做完项目开始之前要做的配置之后,再看一下我们怎么样开始编码。
3.2.1、入口组件
![](/upload/202007/22/202007221103429266.png)
和小程序一样,我们首先编写一个入口组件 app.js。从代码组织上面看,就是一个普通的 React 的 Component,还有 Vue 的实例。首先我们需要去引入对应的框架,然后如果我们引入了样式的话,这份样式就会成为全局的样式。那么在组件内部也可以使用到 Taro 提供的一系列生命周期方法。入口组件会有一个 render 函数,render 函数里面是我们需要渲染的页面。
3.2.2、页面组件
![](/upload/202007/22/202007221103431678.png)
我们写完一个入口组件之后,就要开始编写一系列的页面了。一个普通的页面组件,它同样也是一个 React 的 Component 或者 Vue 的 Component。如果在页面上我们引用了样式文件,这份样式文件就会成为页面级别的样式。同样的在页面内部也可以使用 Taro 提供的一系列生命周期方法。需要注意的是,React 如果要使用 Taro 的一些基础组件,需要从 @tarojs/component 先 import 再使用。而 Vue 则可以直接使用,因为我们借助 vue-loader 去分析用户使用了哪些基础组件。
3.2.3、组件化
![](/upload/202007/22/202007221103433533.png)
3.2.4、生命周期
![](/upload/202007/22/202007221103435154.png)
接下来看一下我们可以使用哪些生命周期。以页面的生命周期为例,Taro 的生命周期分为两部分:第一部分是框架原有的生命周期方法,第二部分就是会以小程序一些比较特色的生命周期方法进行拓展。
3.2.5、组件库
![](/upload/202007/22/202007221103437292.png)
下面介绍组件库,刚刚也有提及,组件在 React 里面需要先引用在使用,原因是什么呢?无论是 Vue 或 React,都需要去引用 Taro 的组件库,Taro 组件库在小程序端会直接使用小程序对应的组件,但是在 H5 端,因为只有HTML 标签,并没有小程序规范的组件,因此我们就使用了 Web Components 去实现了对应微信小程序规范的组件库。
3.2.6、API
![](/upload/202007/22/202007221103438806.png)
接下来看一下API,在小程序里面,所有的小程序规范的 API 在 Taro 里面都是完全支持的。使用上我们首先要从 @tarojs/taro 包里面引入 Taro 对象,然后就可以去调用 Taro 对象里的小程序 API。Taro API 它具体做了什么东西呢?在小程序端其实会直接调用小程序底层的API,只是额外对这些 API 做了 Promise 化的操作。在 H5 端,因为没有这些API,所以我们对大部分常用的小程序规范的 API 进行了一层 Mock。
3.2.7、Ref
![](/upload/202007/22/202007221103441032.png)
最后来介绍一下 Ref, Taro Next 的 Ref 和目前 Taro 的实现有点不一样。如果我们使用框架的 Ref 语法,获取到的会是 Taro 的 HTMLElement 元素,我们可以去获取 HTMLElement 元素的一些节点属性或方法,甚至可以设置 style 以此来去更新视图等。但是如果我们要获取一些节点相关的信息,只能通过小程序提供的获取真实渲染节点的方法,去获取到视图层对应的渲染节点,然后再去获取它的尺寸的信息。
3.3、项目进阶
![](/upload/202007/22/202007221103442536.png)
接下来是介绍项目进阶。
3.3.1、状态管理
![](/upload/202007/22/202007221103443903.png)
在我们的项目越来越庞大的时候,我们可能会引入一些状态管理工具,在目前的 Taro 架构中,如果我们要使用 redux 或 mobx 的话,需要官方先对这些状态管理工具进行兼容,对接 Taro 的渲染机制,然后用户才可以安装使用兼容之后的包。
![](/upload/202007/22/202007221103445250.png)
3.3.2、样式工具
![](/upload/202007/22/202007221103446695.png)
接下来看一下样式工具,刚才也提到了组件之间其实是没有样式隔离的。如果我们要使用样式作用域,我们可以使用CSS Modules。CSS Modules 的配置可以直接在 Taro 的配置文件里面开启。如果用户忠爱于 CSS in JS 这种写法的话,可以使用 linaria 去实现,具体的用法在文档里面有介绍,这里则不作展开了。
3.3.3、渲染 HTML
![](/upload/202007/22/202007221103448306.png)
3.4、多端开发
![](/upload/202007/22/202007221103449868.png)
我们开发完一个项目之后,可能会有一些适配到多端的工作,接下来就介绍一下多端开发相关的知识。
3.4.1、原生小程序页面/组件
![](/upload/202007/22/202007221103451401.png)
首先是使用原生的小程序页面/组件,使用一个原生的小程序页面很简单,只要在入口配置文件里面去配置对应的路由,然后指向那些原生小程序页面就可以了。如果需要使用原生小程序的组件,只要在页面配置里配置 usingComponents 字段,就可以在页面里面去使用这些原生小程序组件。
3.4.2、跨平台开发
![](/upload/202007/22/202007221103453149.png)
接下来是跨平台开发,这里我们提供了两种方式,第一种是环境变量,在 Taro 里面有一个环境变量叫 TARO_ENV,开发者可以使用它去做一些条件判断,根据不同平台使用不同的逻辑。但是如果我们的代码里面有很多这些 if else 的话,其实是很难维护的。
![image.png](/upload/202007/22/202007221103454624.png)
3.4.3、跨框架开发
![](/upload/202007/22/202007221103456684.png)
最后会介绍一下跨框架的开发,我们考虑到可能有些用户需要开发一些在 React 和 Vue 上可以同时使用的组件,我们也提供了一个类似 jQuery 的写法,让用户去编写一个跨框架的组件,然后我们就可以在 React 和 Vue 中同时使用这些组件了。
3.5、性能优化
![](/upload/202007/22/202007221103458412.png)
在开发完一个项目之后,可能我们会去做一些性能优化的工作,接下来就介绍一下性能优化相关的知识。
3.5.1、Taro 对 setData 的优化
![](/upload/202007/22/202007221103459935.png)
首先介绍一下 Taro 对 setData 的优化。第一点是 Taro Next 的 setData 是最小颗粒度的 setData。考虑有以下场景,如果我们要 setData 一个很大的列表,我们在开发原生小程序的时候,常常会担心会不会把一些冗余的数据 setData 到视图层。但是在 Taro Next 里面,我们首先会对这个数据做一个 Hydrate 操作,去识别出渲染时候真正使用到的数据,最终只会 setData 这些渲染用到的数据,这样就可以大大减少 setData 的数据量。
![](/upload/202007/22/202007221103461370.png)
第二点是按路径更新。我们在更新的时候会对新旧的 Taro DOM Tree 进行对比,然后将 diff 的结果使用小程序的按路径更新语法进行 setData,同样也可以大大减少 setData 的数据量。
3.5.2、预渲染
![](/upload/202007/22/202007221103462845.png)
说完了 Taro 本身对于性能的一些优化之外,接下来介绍一下 Taro 提供给用户的一些优化选项。第一个是预渲染Prerender, Taro 的整体渲染流程大概如上图左侧。 React 或 Vu 首先会去渲染出 Taro 的 DOM 树,Taro 内部会对 Taro DOM 树进行一层 Hydrate 操作得出可以 setData 的数据,最后再把数据 setData 到视图层。如果我们初始化的时候,DOM 树非常复杂,那我们 setData 的数据量就会非常大,这样页面就会出现短暂的白屏。因此我们提供了一个预渲染功能,用户可以使用预渲染的功能去预渲染出一个占位页面,然后等到 Taro DOM 树真正的 setData 完成之后,才展示可以真正交互的页面。
3.5.3、React
![](/upload/202007/22/202007221103464222.png)
如果用户在使用 React 的话,那么 shouldComponentUpdate、PureComponent、React.Memo,这些方法都是可以使用的。
3.5.4、长列表优化
![](/upload/202007/22/202007221103466292.png)
接下来介绍的是长列表优化。长列表在我们开发 web 应用时是一个常见的性能瓶颈,因此我们提供了一个VirtualList 虚拟列表组件,虚拟列表组件只会渲染在可视窗口中可见的 item,超出视口之外的这些 item 会被占位的元素所代替,如此就可以限制我们渲染的 item 数量,使得列表的滚动更加顺滑。
3.5.5、体积优化
![](/upload/202007/22/202007221103468537.png)
最后看一下体积相关的优化。Taro 的代码会使用 Webpack 进行打包,因此 Webpack 里面的优化工具我们都是可以使用的。例如代码压缩、tree-shaking、side-effects 等。如果用户还是觉得自己的包比较大,那么就可以使用 webpack-bundle-analyzer 插件去分析自己的包依赖,做出更加细致的优化。
![](/upload/202007/22/202007221103470090.png)
接下来说一下分包,如果用户的主包比较大,可以拆分出一些分包,分包功能在 Taro Next 里面是完全支持的。但这里有一个问题,分包的 node_modules 依赖项默认会被打包到主包的 vendor.js 里面,这时候我们可以使用 splitChunks 做出更细致的优化,把分包对应的 node_modules 依赖单独进行拆分,把拆分后的文件放到对应的分包里面,进一步减少主包的大小。
四、原理浅析
![](/upload/202007/22/202007221103471427.png)
说完怎么样去使用 Taro Next 之后,相信大家已经对 Taro Next 产生了一定的兴趣,这里会对 Taro Next 的部分原理进行一个讲解,包括小程序及 H5 的实现原理。
4.1、设计思路
![](/upload/202007/22/202007221103472863.png)
首先介绍一下我们在小程序端的设计思路。可以看到无论是 React 或者 Vue,他们都会使用到浏览器的 DOM 和 BOM API,然后再渲染到浏览器上。那么我们也同样可以在小程序里面实现一层 DOM 和 BOM,从而让这些框架运行到小程序上。
4.2、DOM渲染方案
![](/upload/202007/22/202007221103474230.png)
但是这里有一个问题,即使我们去得到一棵 Taro DOM 树,又要怎么样去 setData 到视图层?因为小程序并没有提供动态创建节点的能力,我们需要考虑如何使用相对静态的 wxml 来渲染相对动态的 Taro DOM 树。我们使用了模板拼接的方式,根据运行时提供的 DOM 树数据结构,各 templates 递归地相互引用,最终可以渲染出对应的动态 DOM 树。
![](/upload/202007/22/202007221103476339.png)
这里先看一个比较简单的 view 模板实例。上方是一个 view 组件模板,首先我们需要在 template 里面写一个 view,然后把它所有的属性全部列出来(把所有的属性都列出来是因为小程序里面不能去动态地添加属性)。接下来是遍历渲染所有子节点,这些子节点首先会去引用中间层模板,然后中间层模板会根据对应的 nodeName,再去找到对应的组件模板。通过这样的方式把模板一步一步拼接起来,就可以渲染出我们动态的 DOM 树。
4.3、适配 React
![1593261032.jpeg](/upload/202007/22/202007221103478184.png)
接下来看一下怎么样去适配 React。React 架构主要分为 React Core、Reconcliers、Renderers。但是 React DOM 渲染器的体积比较大,里面有很多兼容性代码,放到小程序里面的话就太大了。因此我们就想自己去实现一个渲染器,我们可以提供一个 hostConfig 以对接 Taro DOM 的各 API,从而去实现一个小程序的渲染器。
![image.jpeg](/upload/202007/22/202007221103480322.png)
接下来看一下 React 的整体的渲染流程。首先 React 会使用 taro-react 这个包里面提供的小程序的渲染器,然后再配合 taro-runtime 里面的 createReactPage 函数,去把页面渲染出对应的 Taro DOM 树,然后我们会对 Taro DOM 树做一个 Hydrate 操作,得到需要 setData 的数据,然后进行 setData,视图层会根据这些 data 数据对所有的模板进行拼接,从而渲染出对应的页面。
4.4、Vue 渲染流程
![image.jpeg](/upload/202007/22/202007221103482148.png)
接下来看一下 Vue 的渲染流程。因为 Vue 这边并没有很多冗余代码,因此我们可以直接使用。Vue 同样需要配合 taro-runtime 包里面的 createVuePage 方法,把页面渲染出一个 Taro DOM 树,然后进行 setData,在视图层对这些模板拼接,最终渲染出对应页面。
4.5、Taro Next 小程序端架构
![image.jpeg](/upload/202007/22/202007221103483711.png)
接下来看一下 Taro Next 小程序端的整体架构。首先是用户的 React 或 Vue 的代码会通过 CLI 进行 Webpack 打包,其次在运行时我们会提供 React 和 Vue 对应的适配器进行适配,然后调用我们提供的 DOM 和 BOM API,最后把整个程序渲染到所有的小程序端上面。
4.6、H5 端架构
![image.jpeg](/upload/202007/22/202007221103485077.png)
接下来看一下 H5 端的架构,同样的也是需要把用户的 React 或者 Vue 代码通过 Webpack 进行打包。然后在运行时我们需要去做三件事情:第一件事情是我们需要去实现一个组件库,组件库需要同时给到 React 、Vue 甚至更加多的一些框架去使用,因此我们就使用了 Stencil 去实现了一个基于 WebComponents 且遵循微信小程序规范的组件库,第二、三件事是我们需要去实现一个小程序规范的 API 和路由机制,最终我们就可以把整个程序给运行在浏览器上面。
五、总结与展望
![image.jpeg](/upload/202007/22/202007221103486298.png)
最后说一下对于今天分享的一个总结与展望。
5.1、总结
![image.jpeg](/upload/202007/22/202007221103487821.png)
总结分为四点:
- 首先介绍了我们重构 Taro 的背景,重构是为了解决架构问题,还有提供多框架的支持。
- 其次介绍了 Taro Next 的一些新的特性,Taro Next 现在更强大、更迅速、更灵活了。
- 然后介绍了怎么样使用 Taro Next 去进行开发实践。
- 最后介绍了小程序端还有 H5 端的整体实现原理。
5.2、可定制化拓展
![image.jpeg](/upload/202007/22/202007221103489139.png)
下一步我们会添加可定制化拓展框架的能力,让 Taro 成为开放式的多端框架。背景是我们现在最近正在适配 Vue3,但我们发现要适配 Vue3 我们需要去改动很多处源码相关的地方,而且源码里充斥着各种对于框架的条件判断代码。因此我们就想把 Taro 设计得更加开放。目标是可以直接以 Taro 插件的形式去新增对于框架的支持,而并不需要去改动 Taro 的源码。
5.3、Taro3 新版本
![image.png](/upload/202007/22/202007221103490379.png)
我们 Taro3 的正式版将会在7月初进行发布,相信本文发出时正式版已经发布了。
5.4、联系方式
![image.jpeg](/upload/202007/22/202007221103492654.png)
欢迎大家浏览我们的 Github,可以给我们提 Issues 和 PR。如果有合作意愿或者简历投递的话,可以联系我们的邮箱。扫描上方二维码,即可加入到 Taro 官方交流群。今天我的推荐书是《黑客与画家》,讲述的是 Paul 对技术和创业的思考。今天的分享就到此结束,谢谢大家!
Q:请教JJ:从 Taro 2.0.2 升级到 Taro Next 需要注意什么,升级是无缝的吗?
A:其实还是有一些语法上面需要去修改的,因为以前我们是不需要去引用 React 的,但现在去使用 React 的话,首先需要去引用 React 的包。如果使用 Vue 的话,也需要去引用 Vue 的包。之后我们会提供一个升级相关的插件,给用户现在的语法进行修改,然后进行无缝升级。现在如果想体验的话,也可以参考文档上面的升级指南,其实要改的语法也并不多。
Q:请教JJ:有没有基于Taro React 模式的 SSR 最佳实践,现在 Taro Next 是已经发布正式版本还是预览版本?
A:SSR 的相关功能我们还没去做,之后我们可能会去做,然后正式版的话会在7月1日发布,现在是阿西版本,距离正式版大概还有两个小版本。
Q:请教JJ:看下我的理解对不对?3.0 相比之前主要是增加了运行时的 ReactAdapter、VueAdapter,而不用编译时的模板 AST 编译转换?这样性运行时能会不会差一点?
A:是的,从宏观上可以这样说,从一个编译型的框架转变成一个运行时的框架,现在那些编译时的操作基本是没有了,性能上面的话肯定会比之前通过编译时去适配的话会更差一点。但我们考虑到一点,那就是那些硬件设备,还有环境都会变得更好,所以我们觉得牺牲一点点性能,使用户获得更好的开发体验,这个是值得的。之后我们的方向也会往运行时的框架这一块去靠。
这篇关于跨端跨栈连载 5/7:如何借助 Taro Next 横穿跨端业务线的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)