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

【小程序 - 大智慧】深入微信小程序的核心原理

5.png


目录

  • 课程目标
  • 背景
  • 双线程架构
  • WebView 结构
  • 快速渲染 PageFrame
  • 编译原理
  • Exparser
  • 通讯系统
  • 生命周期
  • 基础库解包
  • 跨端框架
    • 预编译
    • 半编译半运行
    • 运行时框架
  • 主流技术
    • Taro
    • uni-app
    • 汇总
  • 下周安排


课程目标

本次课程主要通过后台管理小程序回顾一下小程序的高阶语法,然后讲解整体小程序流程原理:

  • 前端相关的编码规范、设计规范
  • 页面切换、生命周期、数据通信等基础知识
  • 双线程架构、webview 渲染、PageFrame 模板、通讯系统、生命周期、跨端框架等
  • 掘金小册推荐 https://juejin.cn/book/6982013809212784676

背景

https://zh.wikipedia.org/zh-cn/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F

微信小程序于 2017 年上线,当时企业普遍把 H5 作为公众号的引流入口,公众号正火,但是当时由于 H5 不安全、性能不好、占用存储空间大的问题,微信需要设计一个全新的系统进行迭代。

双线程架构

面试官:说说什么是进程?什么是线程?区别? | web前端面试 - 面试官系列

进程:操作系统进行进行资源分配和调度的基本单位

线程:操作系统能够进行运算调度的最小单位,其是进程中的一个执行任务(控制单元),负责当前进程中程序的执行

微信小程序的设计和前端浏览器是不一致的,它隔离了 JS 操作层 和 界面渲染层,前端是互通的,可以通过 window document 任意的调用 dom 元素和执行脚本,但是小程序作为微信的工具,势必不允许像 web 端这样自由的操作空间,所以:

  1. App Service(逻辑层):单纯执行 JavaScript 的沙箱环境,无法操作 Dom 和访问浏览器 Api ,只能借助 Native 异步查询 DOM 元素并操作,小程序的 WXML 和 WXSS 也会被编译为 JS 脚本进行注入操作。由于小程序内部只有一个 App 实例,通过这个 App 主线程 进行调度
  2. Web View(渲染层):单纯页面的展示,模拟 app 多页面模式,具有多个 webview ,可以暂时抽象成 浏览器的 tab 页面(并非 VUE 的单页面结构,像 App 多页面结构)
  3. Native(微信客户端):利用微信缓存机制,提前注入 微信 SDK、接口请求、组件渲染(wx.request、wx.showToast 都是存放在这里)

WebView 结构

  1. 第一阶段是启动一个 WebView,在iOS和 Android 系统上,操作系统启动WebView都需要一小段时间。
  2. 第二阶段是在 WebView 中初始化基础库,此时还会进行一些基础库内部优化,以提升页面渲染性能。
  3. 第三阶段是注入小程序 WXML 结构和 WXSS 样式,使小程序能在接收到页面初始数据之后马上开始渲染页面(这一阶段无法在小程序启动前执行)。
  4. 每一个页面都独立运行在一个页面层级上。小程序启动时仅有一个页面层级,每次调用 wx.navigateTo,都会创建一个新的页面层级,wx.navigateBack 会销毁一个页面层级。

  1. 微信开发者工具底层是 Chrome XWeb 内核,进行开发跨平台的桌面应用(如QQ、WeChat客户端)。
  2. 左上角选择,微信开发者工具 -> 调试 -> 调试微信开发者工具,和谷歌调试界面几乎一模一样(利用这个工具,我们后续可以处理一些内部报错的调试BUG)。
  3. 接下来,我们利用脚本遍历开发工具的 webview 元素。
// 获取所有的 webview
document.getElementsByTagName('webview')// 打开调试的 webview
document.getElementsByTagName('webview')[0].showDevTools(true, null)
  1. webview 的含义如下:当前小程序的页面 两个渲染层 逻辑层 调试器
  2. 新开一个页面就会新增一个 webview,微信限制最多10个以保证性能问题的底层原因
  3. 利用命令打开一个 webview 页面进行具体的调试
  4. 页面的样式、调试库、渲染库、开发工具的配置…
  5. body 下面的标签就是利用 小程序开发的 Exparser 框架将 dom 转换为自定义组件的一套规则
  6. 每个 webview 都加载了这么多文件,是如何保证高效运作的?

快速渲染 PageFrame

  1. 利用 page frame 模板生成 webview 视图。
  2. 基本的 webview 模板和之前打开的一致,但是包含一些注释占位符,后续会被编译为具体的执行 js 文件。

加载流程如下:

  1. 首页启动时,即第一次通过 pageframe.html 生成内容后,后台服务会缓存 pageframe.html 模板首次生成的html内容。
    1. 非首次新打开页面时,页面请求的 pageframe.html 内容直接走后台缓存。
    2. 非首次新打开页面时,pageframe.html 页面引入的外链js资源(如上图所示)走本地缓存。
  2. 生成 webview 模板后,初始化 webview 地址 http://127.0.0.1:${global.proxyPort}/aboutblank?${c} 空地址,其中 ${c} 为对应 webview 的 id。
  3. 监听页面的 ready 操作,注入执行代码脚本生成最终的 webview 地址和执行代码。

编译原理

基础语法不作过多赘述,主要编译原理和rpx动态适配。WXSS/WXML并不可以直接执行在webview层进行渲染,通过wcsc/wcc执行脚本编译为js文件,然后注入webview中,这里可以演示一下。

// help() 查看编译命令
help()// 编译 WXSS 命令
./wcsc -js index.wxss >> style.js// 编译 WXML 命令
./wcc -js index.wxml >> test.js// 执行 $gwx 文件
var decodeName = decodeURI("./pages/home-tab/index.wxml")
var generateFunc = $gwx(decodeName)generateFunc()
var eps = 1e-4
var transformRPX =window.__transformRpx__ ||function (number, newDeviceWidth) {if (number === 0) return 0number = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth)number = Math.floor(number + eps)if (number === 0) {if (deviceDPR === 1 || !isIOS) {return 1} else {return 0.5}}return number}
  1. wcsc 将 WXSS 编译为 JS 文件。

  2. JS 文件注入到 WebView 中。

  3. 逻辑层执行 JS 文件,主要是设备信息获取(宽度、高度、横屏)、特定规则 rpx 适配为 px,写入编译后的 CSS 文件到 head style 头部。

  4. WCC 将 WXML 编译为 JS 文件。

  5. 但是文件作了压缩混淆,本质逻辑执行 $gwx 函数。

  6. generateFunc 就是接受动态数据,并生成虚拟 DOM 树的函数,DOM 树已存在的数据直接渲染为 wx-view/wx-text,需要 JS 脚本异步获取的数据采取 tag: virtual 虚拟 DOM 元素进行占位,等到获取后端数据之后直接填充 => 真实 DOM。

Exparser

WebComponents Shadow Dom

Exparser是微信小程序的组件组织框架,内置在小程序基础库中,为小程序提供各种各样的组件支撑。内置组件和自定义组件都有Exparser组织管理。

这部分后面单独抽离一篇文章进行讲解…

通讯系统

在正式讲解小程序的通讯系统前,先来熟悉一下小程序的 发布 - 订阅模式

美团一面:你了解发布-订阅模式吗?「每天搞透一道JS手写题💪Day8」 - 掘金

概述:引入中间平台进行注册和通知,有效解决了观察者维护列表导致的解耦不彻底问题

观察者通过 onEventBus 注册事件,然后 Subject 通过 emitEventBus 发射事件,由 EventBus 来向观察者更新。本质上是维护一个 events 对象,通过事件名注入到 events,每个 事件名 里面都有相应的回调函数,发布之后会分发到相应事件 回调函数 的方法。

class PubSub {constructor() {this.events = {};}subscribe(event, callback) {if (typeof event !== 'string') {throw new Error('Event name must be a string');}if (typeof callback !== 'function') {throw new Error('Callback must be a function');}if (!this.events[event]) {this.events[event] = [];}this.events[event].push(callback);}unsubscribe(event, callback) {if (typeof event !== 'string') {throw new Error('Event name must be a string');}if (typeof callback !== 'function') {throw new Error('Callback must be a function');}if (!this.events[event]) return;this.events[event] = this.events[event].filter(cb => cb !== callback);}publish(event, data) {if (typeof event !== 'string') {throw new Error('Event name must be a string');}if (!this.events[event]) return;this.events[event].forEach(callback => callback(data));}
}

在微信小程序执行过程中,Native层(客户端层)分别向渲染层与逻辑层注入 WeixinJSBridge 以达到线程通讯的目的,前面也提到了 webview 脚本注入的原理,WeixinJSBridge 提供了如下几个方法:

  • invoke - 调用 Native API,以api方式调用开发工具提供的基础能力,并提供对应api执行后的回调
  • invokeCallbackHandler - Native 传递 invoke 方法回调结果
  • on - 用来收集小程序开发者工具触发的事件回调
  • publish - 渲染层发布消息,用来向逻辑业务层发送消息,也就是说要调用逻辑层的事件方法
  • subscribe - 订阅逻辑层消息
  • subscribeHandler - 视图层和逻辑层消息订阅转发
  • setCustomPublishHandler - 自定义消息转发

  1. WXML 渲染为虚拟 DOM,添加 addEventListener 进行事件解析。
  2. 逻辑层解析的时候会利用 JSBridge subscribe 订阅事件名称到渲染层,执行逻辑还在逻辑层,只是把名称和具体代码在渲染层作了映射。
  3. 触发事件,渲染层发布消息 publish 携带方法名经过 JSBridge 到达逻辑层。
  4. 逻辑层执行将 Data 以 JSON 字符串格式的数据经过 JSBridge 渲染给 WXML。

生命周期

  1. onLaunch(App onLaunch) App 主应用开始初始化,逻辑线程开始执行。
  2. onLoad(Object query) 页面加载时触发,一个页面只会调用一次,可以在onLoad的参数中获取打开当前页面路径中的参数。
  3. onShow() 页面显示/切入前台时触发。
  4. onHide() 页面隐藏/切入后台时触发。如 wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。
  5. onReady() 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
  6. onUnload() 页面卸载时触发。如 wx.redirectTowx.navigateBack 到其他页面时。
  • wx.navigateTo 方式是创建新的 webview(添加新的页面栈,新加入的页面从头渲染,之前的页面 onHide 隐藏,为了使用 navigateBack 走缓存 onShow)。
  • wx.redirectTo 以及 wx.navigateBack 是通过更新自身 webview 进行页面转换的,所以当前页面会进行卸载操作,并且重新生成新页面。

基础库解包

微信开发者工具里面选择的基础库为微信中的基础库版本(后面标识了兼容性和用户的数量),可用于微信开发者工具内的调试。每个版本的微信客户端都会自带一个版本的小程序基础库,而不是微信客户端带着所有版本的基础库,所以开发时选择的版本尽量和客户端的一致(最新的为好),避免 API 兼容性问题。

接下来,我们利用 openVendor() 找到 基础库进行解析,找到原始的 wxvpkg 然后利用 Github 工具进行反编译出源码,https://github.com/csj5588/wxappUnpacker

构建后的结果在 dist 文件下,本质上还是渲染层和逻辑层两个线程脚本之间的交互流程,后续在深入探讨。

跨端框架

由于小程序语法较为原始,工程化工具不支持,市面上太多平台的小程序需要适配开发,基于此市面上的第三方框架也慢慢进入大众的视野,目前来说流行的就是 taro 和 uni-app。

下面先来介绍下框架的分类:

预编译

画板

本质上是利用 DSL(语法规则) + 语法解析,将一些逻辑转换为小程序支持的语法,但是这样存在一些问题:

  • 如果React或者Vue后期再出一些新特性的话,预编译框架都需要进行语法解析扩展编写。
  • 兼容问题,比如小程序不支持的一些属性,如果不支持,预编译框架要进行兼容。

半编译半运行

基本上运行时的框架都是参考Vue的框架才可以达到运行时的目的,注意小程序是不支持直接操作DOM元素的,所以只需要将Vue的patch挂载真实DOM流程修改为小程序setData的逻辑,template转换为WXML,style适配下规则就可以。

mpvue (github地址请参见)是一个使用Vue.js开发小程序的前端框架。框架基于Vue.js核心,mpvue修改了Vue.js的runtime和compiler实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套Vue.js开发体验。

下面我们来看一下源码是如何实现的?

  1. 修改了 vue 的 patch 阶段进行 this.$updateDataToMP()方法。
  2. this.$updateDataToMP()方法就进行了setData的一个调用,还进行了diffData数据的比对和throttle函数优化双线程通讯的性能。

运行时框架

运行时框架主要解决需要 template 转换为 WXML 这部分逻辑,这部分可以借助小程序的template模版机制来进行解决。

这样的话我们只需要进行 root 数据的操作即可,操作完成后利用 setData 渲染机制 发送到渲染层进行操作即可,Taro4 我看编译的结果似乎也是按照这样的格式操作的,后续再看看。

主流技术

Taro

Taro 介绍 | Taro 文档

Taro 特点总结

  • 采用 TypeScript (TS) 加上部分 Rust 进行开发
  • 底层标准参考 微信小程序,兼容性较好,其他平台的兼容性未知
  • ReactWebpack 语法有良好的兼容性支持,Vue 3 加上 Vite 新推出,也可以用
  • 调试开发需要下载不同平台的工具,无法直接导出运行
  • GitHub 上搜索近两年 stars 30+ 的开源项目,资源只有一页,显示资源较少
  • 不支持使用 Vue 3scoped CSS 样式隔离语法,这可能需要更详细的介绍

资源链接

Taro UI | O2Team

NutUI - 移动端组件库

组件库选择建议

  • Taro 组件库:由 Taro 维护,但不推荐安装
  • NutUI 组件库:多端组件库分离,推荐作为开发的首选

uni-app

uni-app官网
相关资源链接

  • uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架
  • GitHub - Moonofweisheng/wot-design-uni: 一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。
  • 页面 | uni-app官网

uni-app 特点总结

本质上有两种体系:

  • 一种是 uniapp + HBuilder 工具构建的一套自己的规范,其中包含:uts(TypeScript 超集)、uni-modules (依赖管理)、uvue(编译语言)、uniCloud(云服务),最终这些被 uni-app x 统一集成,需要重新学习一套标准、时间成本和难度过高,编辑器也不如前端常用的编辑器 VSCode、WebStorm
  • 另一种可以借助原本的命令行执行,和其他的前端项目一致,可以借助第三方优质模板,但是注意 app 部分打包仍然需要 HBuilder 开发工具(推荐)

汇总

维度Taro得分Uni-app得分
社区文档清晰明确8较为混乱、自有体系和前端不兼容6
上手成本VUE 版本上手容易、React 较高8底层采用 VUE 开发,熟悉程度更高9
开源项目 pushed:>2023-09-01 stars:>3068714310
Github 活跃stars:35.3k+ issues:1.2k + 1w+10stars:39.9k+ issues:0.9k + 3k+8
三方组件库官方组件库统一,资源优质 NutUI VUE 6k+9官方组件库较为简陋、社区UI生态较差、大部分收费、一部分不敢用5
TS 支持兼容性优秀9兼容性优秀8
VUE 语法兼容兼容大部分 VUE 语法7兼容大部分 VUE 语法8
React 语法兼容支持0不支持0
总计🥇🏅🎖️5854

跨端开发框架深度横评

下周安排

开源商城项目拆解

  • 腾讯有数
  • gz-yami - Overview
  • EastWorld

相关文章:

【小程序 - 大智慧】深入微信小程序的核心原理

目录 课程目标背景双线程架构WebView 结构快速渲染 PageFrame编译原理Exparser通讯系统生命周期基础库解包跨端框架预编译半编译半运行运行时框架 主流技术Tarouni-app汇总 下周安排 课程目标 本次课程主要通过后台管理小程序回顾一下小程序的高阶语法,然后讲解整体…...

Qt 去掉QDialog对话框的问号

QT 对话框的问号是什么? QDialog默认的window flag中包含了Qt::WindowContextHelpButtonHint,这个flag意思是在窗口上提供“上下文帮助”按钮 使用方式/调用方式 void QWidget::setWhatsThis(const QString &)比如: ui->lineEdit_1->setWh…...

负载均衡 Ribbon 与 Fegin 远程调用原理

文章目录 一、什么是负载均衡二、Ribbon 负载均衡2.1 Ribbon 使用2.2 Ribbon 实现原理 (★)2.3 Ribbon 负载均衡算法 三、Feign 远程调用3.1 Feign 简述3.2 Feign 的集成3.3 Feign 实现原理 (★) 一、什么是负载均衡 《服务治理:Nacos 注册中心》 末尾提到了负载均…...

c/c++:CMakeLists.txt中添加编译/连接选项使用内存错误检测工具Address Sanitizer(ASan)

Address Sanitizer(ASan)是一个快速的内存错误检测工具。从gcc 4.8开始,AddressSanitizer成为gcc的一部分。 既然是gcc内置的内存检查工具,用起来比第三方的库更方便些。只要指定相应的编译链接参数就可以实现内存泄露检查了,如下是是cmake脚…...

armbian cups 远程打印机 1022

使用 CUPS Web 浏览器界面设置和管理打印机 - Oracle Solaris 管理:常见任务 N1刷armbian变身打印服务器,支持全平台无线打印PC扫描_存储设备_什么值得买 (smzdm.com) 第 6 章 使用 Web 界面向 CUPS 添加打印机 | Red Hat Product Documentation apt…...

three.js使用3DTilesRendererJS加载3d tiles数据

原生的 three.js 目前不支持 3d tiles 数据的加载,不过开源社区已经给出了一些解决方案,其中最活跃的要属 3DTilesRendererJS。它为 three.js 提供了加载和调度 3d tiles 数据的基本能力,虽说和 Cesium.js 对 3d tiles 的支持相比还有很大的差…...

坐牢第三十五天(c++)

一.作业 1.使用模版类自定义栈 代码&#xff1a; #include <iostream> using namespace std; template<typename T> // 封装一个栈 class stcak { private:T *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参…...

Conda离线部署django

要在没有网络连接的环境中使用conda部署Django&#xff0c;你需要预先在有网络连接的机器上创建一个包含所有必要包的环境&#xff0c;并导出该环境的配置文件。然后&#xff0c;你可以将这个配置文件和必要的包传输到目标机器上进行安装。 下面是详细的步骤&#xff1a; 1. …...

1. Fabric.js安装使用

安装 # 安装 fabricjs npm i fabric --save在需要使用的页面引入 import * as fabric from fabric...

Excel中.xls和.xlsx文件格式的区别,及C++操作Excel文件

‌文件结构和兼容性‌&#xff1a; XLS是Excel 97-2003版本的文件格式&#xff0c;而XLSX是Excel 2007及以上版本的文件格式。XLS格式是向下兼容的&#xff0c;意味着较新的Excel版本可以打开XLS文件&#xff0c;但较旧的版本无法打开XLSX文件。相反&#xff0c;XLSX格式是向上…...

php实用命令

php相关命令 命令错误级别 命令 命令命令介绍具体用法php -v查看php版本php -vphp -l检查php文件是否有语法错误php -lphp -m查看当前php安装的扩展php -mphp -i | grep extension_dir查看扩展安装的目录php -i | grep extension_dir 错误级别 命令命令介绍具体用法error_re…...

TypeError:未绑定方法

TypeError: unbound method 错误通常发生在类方法被调用时&#xff0c;但没有正确绑定到实例。这通常意味着你试图在类本身上调用一个实例方法&#xff0c;或者没有使用正确的方式创建类实例。 1、问题背景 某位开发者在尝试创建一个类似于经典的 Pratt 递归下降解析器时遇到了…...

Java虚拟机(JVM)的架构和工作原理,字节码执行流程

JVM的概念 JVM是Java Virtual Machine的缩写&#xff0c; 即Java虚拟机&#xff0c;也被称为Java程序运行的核心环境 。它是一种用于计算设备的规范&#xff0c;‌通过在实际的计算机上仿真模拟各种计算机功能来实现。‌JVM由一套字节码指令集、‌一组寄存器、‌一个栈、‌一个…...

416.分割等和子集

416.分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#xff1a;true 解释&#xff1a;数组可以分割成 [1, 5, 5] 和…...

python初始化一个三维数组

文章目录 1.什么是三维数组2.那我应该如何初始化一个自定义长度的三维数组呢&#xff1f; 1.什么是三维数组 从最外层开始理解&#xff0c;可以理解为一维数组&#xff0c;里面套了一个二维数组&#xff08;12等于三维数组&#xff09; arr [ [[], []], [[], [], []], [[],[]]…...

EI会议推荐-第二届大数据与数据挖掘国际会议(BDDM 2024)

第二届大数据与数据挖掘国际会议&#xff08;BDDM 2024&#xff09; 1、基本信息 大会官网&#xff1a;http://www.icbddm.org/ 官方邮箱&#xff1a;icbddm163.com 主办方&#xff1a;武汉纺织大学 会议时间&#xff1a;2024年12月13日-12月15日 会议地点&#xff1a;湖…...

RK3566/RK3568 Android 11 动态显示/隐藏下拉框

概述 在系统服务中增加显示/隐藏状态栏方法,在上层app动态调用显示/隐藏下拉框方法,设备关机和重启后也能继续生效。 创建全局变量 1.定义全局变量 在frameworks/base/core/java/android/provider/Settings.java中添加 /*** Disable drop-down box* @hide*/public static…...

Android图片缓存工具类LruCache原理和使用介绍

LruCache & DiskLruCache原理。 常用的三级缓存主要有LruCache、DiskLruCache、网络&#xff0c;其中LruCache对应内存缓存、 DiskLruCache对应持久化缓存。Lru表示最近最少使用&#xff0c;意思是当缓存到达限制时候&#xff0c;优先淘汰近 期内最少使用的缓存&#xff0c…...

生活杂记1

生命中&#xff0c;总有一些事需要你一生去治愈&#xff0c;我把这些杂记写出来&#xff0c;写完了就不再想了&#xff0c;太内耗了…hahaha~ 因为嘴馋&#xff0c;小时候经常去老姑家&#xff0c;她家有各类零食及平时很少吃的“山珍海味”。去的次数多了&#xff0c;就和她家…...

go常用代码

连接阿波罗&#xff1a; 默认properties类型 package mainimport ("fmt""github.com/apolloconfig/agollo/v4""github.com/apolloconfig/agollo/v4/env/config" )func main() {c : &config.AppConfig{AppID: "2222",Cl…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...