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

「Vue源码学习」常见的 Vue 源码面试题,看完可以说 “精通Vue” 了吗?

Vue源码面试题

  • 一、行时(Runtime)+ 编译器(Compiler) vs. 只包含运行时(Runtime-only)
    • webpack
    • Rollup
    • Browserify
  • 二、Vue 的初始化过程(
    • 面试关问:new Vue(options) 发生了什么?
  • 三、响应式原理
    • 1. 面试官 问:Vue 响应式原理是怎么实现的?
      • 答:
    • 2. 面试官问:methods、computed 和 watch 有什么区别?
      • 答:
  • 四、异步更新
    • 1. 面试官 问:Vue 的异步更新机制是如何实现的?
      • 答:
    • 2. 面试关 问:Vue 的 nextTick API 是如何实现的?
      • 答:
  • 五、全局API
    • 1. 面试官 问:Vue.use(plugin) 做了什么?
      • 答:
    • 2. 面试官 问:Vue.mixin(options) 做了什么?
      • 答:
    • 3. 面试官 问:Vue.component(compName, Comp) 做了什么?
      • 答:
    • 4. 面试官 问:Vue.directive('my-directive', {xx}) 做了什么?
      • 答:
    • 5. 面试官 问:Vue.filter('my-filter', function(val) {xx}) 做了什么?
      • 答:
    • 6. 面试官 问:Vue.extend(options) 做了什么?
      • 答:
    • 7. 面试官 问:Vue.set(target, key, val) 做了什么
      • 答:
    • 8. 面试官 问:Vue.delete(target, key) 做了什么?
      • 答:
    • 9. 面试官 问:Vue.nextTick(cb) 做了什么?
      • 答:
  • 六、实例方法
    • 1. 面试官 问:vm.$set(obj, key, val) 做了什么?
      • 答:
  • 博主最近在准备面试,未完待续!

一、行时(Runtime)+ 编译器(Compiler) vs. 只包含运行时(Runtime-only)

-如果你需要动态编译模版(比如:将字符串模版传递给 template 选项,或者通过提供一个挂载元素的方式编写 html 模版),你将需要编译器,因此需要一个完整的构建包。

当你使用 vue-loader 或者 vueify 时,*.vue 文件中的模版在构建时会被编译为 JavaScript 的渲染函数。因此你不需要包含编译器的全量包,只需使用只包含运行时的包即可。

只包含运行时的包体积要比全量包的体积小 30%。因此尽量使用只包含运行时的包,如果你需要使用全量包,那么你需要进行如下配置:

webpack

module.exports = {// ...resolve: {alias: {'vue$': 'vue/dist/vue.esm.js'}}
}

Rollup

const alias = require('rollup-plugin-alias')rollup({// ...plugins: [alias({'vue': 'vue/dist/vue.esm.js'})]
})

Browserify

{// ..."browser": {"vue": "vue/dist/vue.common.js"}
}

二、Vue 的初始化过程(

面试关问:new Vue(options) 发生了什么?

从入口代码开始分析,我们先来分析 new Vue 背后发生了哪些事情。我们都知道,new 关键字在 Javascript 语言中代表实例化是一个对象,而 Vue 实际上是一个类,类在 Javascript 中是用 Function 来实现的,来看一下源码,在src/core/instance/index.js 中。

function Vue (options) {if (process.env.NODE_ENV !== 'production' &&!(this instanceof Vue)) {warn('Vue is a constructor and should be called with the `new` keyword')}this._init(options)
}

可以看到 Vue 只能通过 new 关键字初始化,然后会调用 this._init 方法, 该方法在 src/core/instance/init.js 中定义。

Vue.prototype._init = function (options?: Object) {const vm: Component = this// a uidvm._uid = uid++let startTag, endTag/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && config.performance && mark) {startTag = `vue-perf-start:${vm._uid}`endTag = `vue-perf-end:${vm._uid}`mark(startTag)}// a flag to avoid this being observedvm._isVue = true// merge optionsif (options && options._isComponent) {// optimize internal component instantiation// since dynamic options merging is pretty slow, and none of the// internal component options needs special treatment.initInternalComponent(vm, options)} else {vm.$options = mergeOptions(resolveConstructorOptions(vm.constructor),options || {},vm)}/* istanbul ignore else */if (process.env.NODE_ENV !== 'production') {initProxy(vm)} else {vm._renderProxy = vm}// expose real selfvm._self = vminitLifecycle(vm)initEvents(vm)initRender(vm)callHook(vm, 'beforeCreate')initInjections(vm) // resolve injections before data/propsinitState(vm)initProvide(vm) // resolve provide after data/propscallHook(vm, 'created')/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && config.performance && mark) {vm._name = formatComponentName(vm, false)mark(endTag)measure(`vue ${vm._name} init`, startTag, endTag)}if (vm.$options.el) {vm.$mount(vm.$options.el)}
}

Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等。

三、响应式原理

1. 面试官 问:Vue 响应式原理是怎么实现的?

答:

  • 响应式的核心是通过 Object.defineProperty 拦截对数据的访问和设置

  • 响应式的数据分为两类:

    • 添加新数据时进行响应式处理,然后由 dep 通知 watcher 去更新
    • 删除数据时,也要由 dep 通知 watcher 去更新
    • 访问数据时(obj.key)进行依赖收集,在 dep 中存储相关的 watcher
    • 设置数据时由 dep 通知相关的 watcher 去更新
    • 对象,循环遍历对象的所有属性,为每个属性设置 getter、setter,以达到拦截访问和设置的目的,如果属性值依旧为对象,则递归为属性值上的每个 key 设置 getter、setter
    • 数组,增强数组的那 7 个可以更改自身的原型方法,然后拦截对这些方法的操作

2. 面试官问:methods、computed 和 watch 有什么区别?

答:

<!DOCTYPE html>
<html lang="en"><head><title>methods、computed、watch 有什么区别</title>
</head><body><div id="app"><!-- methods --><div>{{ returnMsg() }}</div><div>{{ returnMsg() }}</div><!-- computed --><div>{{ getMsg }}</div><div>{{ getMsg }}</div></div><script src="../../dist/vue.js"></script><script>new Vue({el: '#app',data: {msg: 'test'},mounted() {setTimeout(() => {this.msg = 'msg is changed'}, 1000)},methods: {returnMsg() {console.log('methods: returnMsg')return this.msg}},computed: {getMsg() {console.log('computed: getMsg')return this.msg + ' hello computed'}},watch: {msg: function(val, oldVal) {console.log('watch: msg')new Promise(resolve => {setTimeout(() => {this.msg = 'msg is changed by watch'}, 1000)})}}})</script>
</body></html>
  • 使用场景
    • methods 一般用于封装一些较为复杂的处理逻辑(同步、异步)
    • computed 一般用于封装一些简单的同步逻辑,将经过处理的数据返回,然后显示在模版中,以减轻模版的重量
    • watch 一般用于当需要在数据变化时执行异步或开销较大的操作
  • 区别
    • methods VS computed

      如果在一次渲染中,有多个地方使用了同一个 methods 或 computed 属性,methods 会被执行多次,而 computed 的回调函数则只会被执行一次。

      在一次渲染中,多次访问 computedProperty,只会在第一次执行 computed 属性的回调函数,后续的其它访问,则直接使用第一次的执行结果watcher.value),而这一切的实现原理则是通过对 watcher.dirty 属性的控制实现的。而 methods每一次的访问则是简单的方法调用(this.xxMethods)。

    • computed VS watch

      computed 和 watch 的本质是一样的,内部都是通过 Watcher 来实现的,其实没什么区别,非要说区别的话就两点:1、使用场景上的区别,2、computed 默认是懒执行的,切不可更改

    • methods VS watch

      methods 和 watch 之间其实没什么可比的,完全是两个东西,不过在使用上可以把 watch 中一些逻辑抽到 methods 中,提高代码的可读性。

四、异步更新

1. 面试官 问:Vue 的异步更新机制是如何实现的?

答:

Vue 的异步更新机制的核心是利用了浏览器的异步任务队列来实现的,首选微任务队列,宏任务队列次之

  • 当响应式数据更新后,会调用 dep.notify 方法,通知 dep 中收集的 watcher 去执行 update 方法,watcher.update 将 watcher 自己放入一个 watcher 队列(全局的 queue 数组)。

  • 然后通过 nextTick 方法将一个刷新 watcher 队列的方法(flushSchedulerQueue)放入一个全局的 callbacks 数组中。

  • 如果此时浏览器的异步任务队列中没有一个叫 flushCallbacks 的函数,则执行 timerFunc 函数,将 flushCallbacks 函数放入异步任务队列。如果异步任务队列中已经存在 flushCallbacks 函数,等待其执行完成以后再放入下一个 flushCallbacks 函数。

flushCallbacks 函数负责执行 callbacks 数组中的所有 flushSchedulerQueue 函数。

flushSchedulerQueue 函数负责刷新 watcher 队列,即执行 queue 数组中每一个 watcher 的 run 方法,从而进入更新阶段,比如执行组件更新函数或者执行用户 watch 的回调函数。

2. 面试关 问:Vue 的 nextTick API 是如何实现的?

答:

Vue.nextTick 或者 vm.$nextTick 的原理其实很简单,就做了两件事:

  • 将传递的回调函数用 try catch 包裹然后放入 callbacks 数组

  • 执行 timerFunc 函数,在浏览器的异步任务队列放入一个刷新 callbacks 数组的函数

五、全局API

1. 面试官 问:Vue.use(plugin) 做了什么?

答:

负责安装 plugin 插件,其实就是执行插件提供的 install 方法。

  • 首先判断该插件是否已经安装过
  • 如果没有,则执行插件提供的 install 方法安装插件,具体做什么有插件自己决定

2. 面试官 问:Vue.mixin(options) 做了什么?

答:

负责在 Vue 的全局配置上合并 options 配置。然后在每个组件生成 vnode 时会将全局配置合并到组件自身的配置上来。

  • 标准化 options 对象上的 props、inject、directive 选项的格式
  • 处理 options 上的 extends 和 mixins,分别将他们合并到全局配置上
  • 然后将 options 配置和全局配置进行合并,选项冲突时 options 配置会覆盖全局配置

3. 面试官 问:Vue.component(compName, Comp) 做了什么?

答:

负责注册全局组件。其实就是将组件配置注册到全局配置的 components 选项上(options.components),然后各个子组件在生成 vnode 时会将全局的 components 选项合并到局部的 components 配置项上。

  • 如果第二个参数为空,则表示获取 compName 的组件构造函数
  • 如果 Comp 是组件配置对象,则使用 Vue.extend 方法得到组件构造函数,否则直接进行下一步
  • 在全局配置上设置组件信息,this.options.components.compName = CompConstructor

4. 面试官 问:Vue.directive(‘my-directive’, {xx}) 做了什么?

答:

在全局注册 my-directive 指令,然后每个子组件在生成 vnode 时会将全局的 directives 选项合并到局部的 directives 选项中。原理同 Vue.component 方法:

  • 如果第二个参数为空,则获取指定指令的配置对象
  • 如果不为空,如果第二个参数是一个函数的话,则生成配置对象
  • 然后将指令配置对象设置到全局配置上,this.options.directives['my-directive'] = {xx}

5. 面试官 问:Vue.filter(‘my-filter’, function(val) {xx}) 做了什么?

答:

负责在全局注册过滤器 my-filter,然后每个子组件在生成 vnode 时会将全局的 filters 选项合并到局部的 filters 选项中。原理是:

  • 如果没有提供第二个参数,则获取 my-filter 过滤器的回调函数
  • 如果提供了第二个参数,则是设置 this.options.filters['my-filter'] = function(val) {xx}

6. 面试官 问:Vue.extend(options) 做了什么?

答:

Vue.extend 基于 Vue 创建一个子类,参数 options 会作为该子类的默认全局配置,就像 Vue 的默认全局配置一样。所以通过 Vue.extend 扩展一个子类,一大用处就是内置一些公共配置,供子类的子类使用。

  • 定义子类构造函数,这里和 Vue 一样,也是调用 _init(options)
  • 合并 Vue 的配置和 options,如果选项冲突,则 options 的选项会覆盖 Vue 的配置项
  • 给子类定义全局 API,值为 Vue 的全局 API,比如 Sub.extend = Super.extend,这样子类同样可以扩展出其它子类
  • 返回子类 Sub

7. 面试官 问:Vue.set(target, key, val) 做了什么

答:

由于 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = ‘hi’),所以通过 Vue.set 为向响应式对象中添加一个 property,可以确保这个新 property 同样是响应式的,且触发视图更新。

  • 更新数组指定下标的元素:Vue.set(array, idx, val),内部通过 splice 方法实现响应式更新
  • 更新对象已有属性:Vue.set(obj, key ,val),直接更新即可 => obj[key] = val
  • 不能向 Vue 实例或者 $data 动态添加根级别的响应式数据
  • Vue.set(obj, key, val),如果 obj 不是响应式对象,会执行 obj[key] = val,但是不会做响应式处理
  • Vue.set(obj, key, val),为响应式对象 obj 增加一个新的 key,则通过 defineReactive 方法设置响应式,并触发依赖更新

8. 面试官 问:Vue.delete(target, key) 做了什么?

答:

删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到 property 被删除的限制,但是你应该很少会使用它。当然同样不能删除根级别的响应式属性。

  • Vue.delete(array, idx),删除指定下标的元素,内部是通过 splice 方法实现的
  • 删除响应式对象上的某个属性:Vue.delete(obj, key),内部是执行 delete obj.key,然后执行依赖更新即可

9. 面试官 问:Vue.nextTick(cb) 做了什么?

答:

Vue.nextTick(cb) 方法的作用是延迟回调函数 cb 的执行,一般用于 this.key = newVal 更改数据后,想立即获取更改过后的 DOM 数据:

this.key = 'new val'Vue.nextTick(function() {// DOM 更新了
})

其内部的执行过程是:

  • this.key = 'new val,触发依赖通知更新,将负责更新的 watcher 放入 watcher 队列
  • 将刷新 watcher 队列的函数放到 callbacks 数组中
  • 在浏览器的异步任务队列中放入一个刷新 callbacks 数组的函数
  • Vue.nextTick(cb) 来插队,将 cb 函数放入 callbacks 数组
  • 待将来的某个时刻执行刷新 callbacks 数组的函数
  • 然后执行 callbacks 数组中的众多函数,触发 watcher.run 的执行,更新 DOM
  • 由于 cb 函数是在后面放到 callbacks 数组,所以这就保证了先完成的 DOM 更新,再执行 cb 函数

六、实例方法

1. 面试官 问:vm.$set(obj, key, val) 做了什么?

答:

vm.$set 用于向响应式对象添加一个新的 property,并确保这个新的 property 同样是响应式的,并触发视图更新。由于 Vue 无法探测对象新增属性或者通过索引为数组新增一个元素,比如:this.obj.newProperty = 'val'this.arr[3] = 'val'。所以这才有了 vm.$set,它是 Vue.set 的别名。

  • 为对象添加一个新的响应式数据:调用 defineReactive 方法为对象增加响应式数据,然后执行 dep.notify 进行依赖通知,更新视图
  • 为数组添加一个新的响应式数据:通过 splice 方法实现

博主最近在准备面试,未完待续!

相关文章:

「Vue源码学习」常见的 Vue 源码面试题,看完可以说 “精通Vue” 了吗?

Vue源码面试题一、行时&#xff08;Runtime&#xff09; 编译器&#xff08;Compiler&#xff09; vs. 只包含运行时&#xff08;Runtime-only&#xff09;webpackRollupBrowserify二、Vue 的初始化过程&#xff08;面试关问&#xff1a;new Vue(options) 发生了什么&#xff1…...

FreeModbus RTU 移植指南

FreeModbus 简介 FreeModbus 是一个免费的软件协议栈&#xff0c;实现了 Modbus 从机功能&#xff1a; 纯 C 语言支持 Modbus RTU/ASCII支持 Modbus TCP 本文介绍 Modbus RTU 移植。 移植环境&#xff1a; 裸机Keil MDK 编译器Cortex-M3 内核芯片&#xff08;LPC1778/88&…...

《唐诗三百首》数据源网络下载

2023年的 元宵之夜&#xff0c;这场以“长安”为主题的音乐会火了&#xff01;在抖音&#xff0c;超过2300万人次观看了直播&#xff0c;在线同赏唐诗与交响乐的融合。许多网友惊呼&#xff0c;上学时那些害怕背诵的诗句&#xff0c;原来还可以有这么美的表达这场近80分钟的音乐…...

(深度学习快速入门)第五章第一节2:GAN经典案例之MNIST手写数字生成

获取pdf&#xff1a;密码7281 文章目录一&#xff1a;数据集介绍二&#xff1a;GAN简介&#xff08;1&#xff09;简介&#xff08;2&#xff09;损失函数三&#xff1a;代码编写&#xff08;1&#xff09;参数及数据预处理&#xff08;2&#xff09;生成器与判别器模型&#x…...

雁过留痕,竟是病毒的痕迹?

凌恩生物全新升级宏病毒组分析流程&#xff1b;聚焦DNA&#xff0c;RNA病毒组研究热点&#xff1b;高灵敏度检测vOTUs&#xff1b;多软件整合&#xff0c;精准鉴定病毒序列&#xff1b;直击地化循环关键环节&#xff0c;助力宏病毒组科研成功&#xff01;期刊&#xff1a;Micro…...

Linux基本功系列之sort命令实战

文章目录前言一. sort命令介绍二. 语法格式及常用选项三. 参考案例3.1 按照文本默认排序3.2 忽略相同的行3.3 按数字大小进行排序3.4 检查文件是否已经按照顺序排序3.5 将第3列按照数字大小进行排序3.6 将排序结果输出到文件四. 探讨 -k的高级用法总结前言 大家好&#xff0c;…...

【笔记】移动端自动化:adb调试工具+appium+UIAutomatorViewer

学习源&#xff1a; https://www.bilibili.com/video/BV11p4y197HQ https://blog.csdn.net/weixin_47498728/category_11818905.html 一、移动端测试环境搭建 学习目标 1.能够搭建java 环境 2.能够搭建android 环境 &#xff08;一&#xff09;整体思路 我们的目标是Andr…...

面试复习题--性能检测原理

1、布局性能检测 Systrace&#xff0c;内存优化工具中也用到了 Systrace,这里关注 Systrace 中的 Frames 页面&#xff0c;正常情况下圆点为绿色&#xff0c;当出现黄色或者红色的圆点时&#xff0c;表现出现了丢帧。 Layout Inspector&#xff0c;是 AndroidStudio 自带工具…...

@LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析

背景 最近引入了 Nacos Config 配置管理能力&#xff0c;说起来用法很简单&#xff0c;还是踩了三个坑。 Nacos Config 的 nacos 的帐号密码加密配置后&#xff0c;怎么解密而且在 NacosConfigBootstrapConfiguration 真正注入 Nacos Config 注入之前&#xff0c;而且不能触发…...

2023年个人计划

2023年个人计划 可能是最近太清闲&#xff0c;感觉生活很无聊&#xff0c;就胡乱做下新年的规划吧&#xff0c;扰乱下烦闷的心 1 二宝健健康康&#xff0c;活泼可爱 目前老婆已经怀孕5周左右了&#xff0c;二宝将在进行年中降生&#xff0c;希望老婆少受点罪&#xff0c;二宝…...

加拿大访问学者家属如何办理探亲签证?

由于大多数访问学者的访学期限都为一年&#xff0c;家人来访不仅可以缓解访学的寂寞生活&#xff0c;而且也是家人到加拿大体验国外风情的好机会。家属在国内申请赴加签证时&#xff0c;如果材料齐全&#xff0c;一般上午递交了申请&#xff0c;下午就可以拿到签证。以下是家人…...

操作系统基础---多线程

文章目录操作系统基础---多线程1.为何引入线程程序并发的时空开销线程的设计思路线程的状态和线程控制块TCB2.线程与进程的比较3.线程的实现⭐1.内核支持线程KST2.用户级线程3.组合方式操作系统基础—多线程 1.为何引入线程 利用传统的进程概念和设计方法已经难以设计出适合于…...

2022-12-10青少年软件编程(C语言)等级考试试卷(六级)解析

2022-12-10青少年软件编程&#xff08;C语言&#xff09;等级考试试卷&#xff08;六级&#xff09;解析T1、区间合并 给定 n 个闭区间 [ai; bi]&#xff0c;其中i1,2,...,n。任意两个相邻或相交的闭区间可以合并为一个闭区间。例如&#xff0c;[1;2] 和 [2;3] 可以合并为 [1;3…...

太酷了,用Python实现一个动态条形图!

大家好&#xff0c;我是小F&#xff5e;说起动态条形图&#xff0c;小F之前推荐过两个Python库&#xff0c;比如「Bar Chart Race」、「Pandas_Alive」&#xff0c;都可以实现。今天就给大家再介绍一个新的Python库「pynimate」&#xff0c;一样可以制作动态条形图&#xff0c;…...

单元测试junit+mock

单元测试 是什么&#xff1f; 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证。至于“单元”的大小或范围&#xff0c;并没有一个明确的标准&#xff0c;“单元”可以是一个方法、类、功能模块或者子系统。 单元测试通…...

2022Q4手机银行新版本聚焦提升客群专属、财富开放平台、智能化能力,活跃用户规模6.91亿人

易观&#xff1a;2022年第4季度&#xff0c;手机银行APP迭代升级加快&#xff0c;手机银行作为零售银行服务及经营的主阵地&#xff0c;与零售银行业务发展的联系日益紧密。迭代升级一方面可以顺应零售银行发展战略及方向&#xff0c;对手机银行业务布局进行针对性调整优化&…...

YOLO-V1~V3经典物体检测算法介绍

大名鼎鼎的YOLO物体检测算法如今已经出现了V8版本&#xff0c;我们先来了解一下它前几代版本都做了什么吧。本篇文章介绍v1-v3&#xff0c;后续会继续更新。一、节深度学习经典检测方法概述1.1 检测任务中阶段的意义我们所学的深度学习经典检测方法 &#xff0c;有些是单阶段的…...

SparkSQL 核心编程

文章目录SparkSQL 核心编程1、新的起点2、SQL 语法1) 读取 json 文件创建 DataFrame2) 对 DataFrame 创建一个临时表3) 通过SQL语句实现查询全表3、DSL 语法1) 创建一个DataFrame2) 查看DataFrame的Schema信息3) 只查看"username"列数据4) 查看"username"列…...

Android核心开发【UI绘制流程解析+原理】

一、UI如何进行具体绘制 UI从数据加载到具体展现的过程&#xff1a; 进程间的启动协作&#xff1a; 二、如何加载到数据 应用从启动到onCreate的过程&#xff1a; Activity生产过程详解&#xff1a; 核心对象 绘制流程源码路径 1、Activity加载ViewRootImpl ActivityThread…...

计算机组成原理第七章笔记记录

仅仅作为笔记记录,B站视频链接&#xff0c;若有错误请指出&#xff0c;谢谢 基本概念 演变过程 I/O系统基本组成 I/O软件 包括驱动程序、用户程序、管理程序、升级补丁等 下面的两种方式是用来实现CPU和I/O设备的信息交换的 I/O指令 CPU指令的一部分,由操作码,命令码,设备…...

ORB-SLAM2编译、安装等问题汇总大全(Ubuntu20.04、eigen3、pangolin0.5、opencv3.4.10)

ORB-SLAM2编译、安装等问题汇总大全&#xff08;Ubuntu20.04、eigen3、pangolin0.5、opencv3.4.10&#xff09; 1&#xff1a;环境说明: 使用的Linux发行版本为Ubuntu 20.04 SLAM2下载地址为&#xff1a;git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2 2&a…...

QuickBuck:一款专为安全研究人员设计的勒索软件模拟器

关于QuickBuck QuickBuck是一款基于Golang开发的勒索软件模拟工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以通过更简单的方法来判断反病毒保护方案是否能够有效地预防勒索软件的攻击。 功能介绍 该工具能够模拟下列勒索软件典型行为&#xff0c;其中包括&a…...

【八大数据排序法】堆积树排序法的图形理解和案例实现 | C++

第二十一章 堆积树排序法 目录 第二十一章 堆积树排序法 ●前言 ●认识排序 1.简要介绍 2.图形理解 3.算法分析 ●二、案例实现 1.案例一 ● 总结 前言 排序算法是我们在程序设计中经常见到和使用的一种算法&#xff0c;它主要是将一堆不规则的数据按照递增…...

低代码开发平台|生产管理-生产加工搭建指南

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建生产管理-生产加工。1.2、应用场景在主生产计划列表中下达加工后&#xff0c;在加工单列表可操作领料、质检。2、设置方法2.1、表单搭建1&#xff09;新建表单【产品结构清单&#xff08;BOM&#xff09;】&#xff0c;字段…...

Python类型-语句-函数

文章目录类型动态类型:变量类型会随着程序的运行发生改变注释控制台控制台输入input()运算符算术关系逻辑赋值总结语句判断语句while循环for循环函数链式调用和嵌套调用递归关键字传参在C/java中&#xff0c;整数除以整数结果还是整数&#xff0c;并不会将小数部分舍弃&#xf…...

真兰仪表在创业板开启申购:募资约20亿元,IPO市值约为78亿元

2月9日&#xff0c;上海真兰仪表科技股份有限公司&#xff08;下称“真兰仪表”&#xff0c;SZ:301303&#xff09;开启申购&#xff0c;将在深圳证券交易所创业板上市。本次上市&#xff0c;真兰仪表的发行价为26.80元/股&#xff0c;市盈率43.06倍。 据贝多财经了解&#xf…...

【2023】Prometheus-Prometheus与Alertmanager配置详解

记录一下Prometheus与Alertmanager的配置参数等内容 目录1.Prometheus1.1.prometheus.yml1.2.告警规则定义2.alertmanager2.1.alertmanager.yml2.1.1.global&#xff1a;全局配置2.1.1.1.以email方式作为告警发送方2.1.1.2.以wechat方式作为告警发送方2.1.1.3.以webhook方式作为…...

华为HCIE学习之openstack基础

文章目录一、Openstack各种文件位置二、Openstack命令操作1.使用帮助三、用命令发放云主机1、创建租户2、创建用户并与租户绑定3、注册镜像4、创建规格5、创建公有网络及其子网&#xff08;做弹性IP用&#xff09;6、创建私有网络及其子网7、创建路由并设置网关与端口8、创建安…...

Python实现贝叶斯优化器(Bayes_opt)优化BP神经网络分类模型(BP神经网络分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。1.项目背景贝叶斯优化器(BayesianOptimization) 是一种黑盒子优化器&#xff0c;用来寻找最优参数。贝叶斯优化器是基…...

Elasticsearch(九)搜索---搜索辅助功能(下)--搜索性能分析

一、前言 上篇文章我们学习了ES的搜索辅助功能的一部分–分别是指定搜索返回的字段&#xff0c;搜索结果计数&#xff0c;分页&#xff0c;那么本次我们来学习一下ES的性能分析相关功能。 二、ES性能分析 在使用ES的过程中&#xff0c;有的搜索请求的响应比较慢&#xff0c;…...

广州制作网站公司电话/g3云推广

文章目录题目描述输入描述输出描述输入输出样例最终代码1. c/c2. java3. python过程理解题目描述 题目背景 在游戏《星际争霸 II》中&#xff0c;高阶圣堂武士作为星灵的重要 AOE 单位&#xff0c;在 游戏的中后期发挥着重要的作用&#xff0c;其技能"灵能风暴"可以…...

图片描述 wordpress/国家高新技术企业

待补充转载于:https://www.cnblogs.com/zcjboke/p/5514547.html...

太仓做网站公司/泉州关键词排名

问题描述搜索输入框中&#xff0c;只当用户停止输入后&#xff0c;才进行后续的操作&#xff0c;比如发起Http请求等。学过电子电路的同学应该知道按键防抖。原理是一样的&#xff1a;就是说当调用动作n毫秒后&#xff0c;才会执行该动作&#xff0c;若在这n毫秒内又调用此动作…...

建设网站的3个必要条件/seo是什么软件

根据《网络世界》报道&#xff1a; 搜索巨人Google于7月21日发布了2006年第二财季财报&#xff0c;因为成功躲避了影响雅虎和易趣的行业增长减缓趋势&#xff0c;Google利润增长达到了110%。尽管Google的增长依然强劲&#xff0c;甚至高出华尔街分析师的预测&#xff0c;但这并…...

武汉网站制作好/数据网站

之前我们做的都是单表查询&#xff0c;那么问题来了&#xff0c;如果我们想要做多表关联查询该怎么处理呢&#xff0c;本篇Blog来探索关联查询&#xff08;多对一关系&#xff09;和集合查询&#xff08;一对多关系&#xff09;的实现方式。同样还是在之前的Person表基础上做一…...

葫芦岛城乡建设委员会网站/今日油价92汽油价格表

http://acm.hdu.edu.cn/showproblem.php?pid3207 一道看上去好像是线段树的题&#xff0c;不过因为有两种操作&#xff08;区间增加相同的数&#xff0c;以及将区间中比给出的数小的数更新成给出的数&#xff09;&#xff0c;所以用一般的线段数是不能正确更新的。这题应该是可…...