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

Vue 3 常见面试题汇总

前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

前言

最近两年许多大厂都在实行“降本增效”、“优化组织架构”,然后“为社会输送了大量人才”,今年(2023)更是不容易,一些外资企业也陆续撤离,各行各业订单大量减少,业务大量裁撤,导致工作岗位大幅度减少。程序员们不得不重新找工作,其中不少人回到了老家,不少人送起了外卖,跑起了网约车。当然也有不少人选择继续在坚持,不管做出了什么选择,各位的选择都值得被尊重。在这个时代环境下,大家都是好样的。

而我选择了继续坚持,最近也在找工作的路上,总结了一些面试题,如果你目前主要的的技术栈是 Vue,或者需要从别的框架转到 Vue,希望这篇面试题能帮到你。

谈谈你对 Vue 的理解?为什么选择 Vue?

根据官方说法,Vue 是一套用于构建用户界面的渐进式框架。Vue 的设计受到了 MVVM 的启发。Vue 的两个核心是数据驱动组件系统

我为什么使用 Vue,有以下几个原因:

  • Vue 对于前端初学者比较友好。一个 Vue 文件的结构和原生 HTML 保持了高度相似,分为模板、脚本和样式,这种写法可以让前端初学者快速入门。

  • 其次,就是 Vue 提供一套高效的响应式系统用于更新 DOM,可以让开发者专注于处理业务。

  • 最后,Vue 提供了许多 JS 定制化的操作,比如指令和是修饰符,开发者可以直接使用,帮助开发者们减少了大量时间。

什么是 MVVM,可以介绍一下吗?

MVVM,即 Model–View–ViewModel,是一种软件架构模式。

  • Model

    即模型,是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。

  • View

    即视图,是用户在屏幕上看到的结构、布局和外观(UI)。

  • ViewModel

    即视图模型,是暴露公共属性和命令的视图的抽象。用于把 Model 和 View 关联起来。ViewModel 负责把 Model 的数据同步到 View 显示出来,还负责把 View 的修改同步回 Model 。

MVVM

在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的,View 数据的变化会同步到 Model 中,而 Model 数据的变化也会立即反应到 View 上。

因此开发者只需关注业务逻辑,不需要手动操作 DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

Vue 响应式系统的原理

Vue 实现响应式主要是采用数据劫持结合发布者-订阅者模式的方式。具体实现就是整合 Observer,Compiler 和 Watcher 三者。

  • Observer

    观察者。Vue 通过 Observer 对数据对象的所有属性进行监听,当把一个普通对象传给 Vue 实例的 data 选项时,Observer 将遍历它的所有属性,并为其添加 getter 和 settergetter 将收集此属性所有的订阅者,setter 将在属性发生变动的时候,重新为此属性赋值,并通知订阅者调用其对应的更新函数。

    在 Vue 2 中是通过 ES5 的 Object.defineProperty() 方法实现。

    在 Vue 3 中是通过 ES6 的 new Proxy() 实现的。

  • Compiler

    模板编译器。它的作用是对每个元素节点的指令 v- 和模板语法 {{}} 进行扫描,替换对应的真实数据,或绑定相应的事件函数。

  • Watcher

    发布者/订阅者。Watcher 作为连接 Observer 和 Compiler 的桥梁,能够订阅并收到每个属性变动的通知,然后执行相应的回调函数。Compiler 在编译时通过 Watcher 绑定对应的数据更新回调函数,Observer 在监听到数据变化时执行此回调。在 Observer 中,Watcher 就是订阅者,在 Compiler 中,Watcher 就是发布者。

Vue 3.x 带来了哪些新的特性和性能方面的提升?

  1. 引入了 Composition API(组合式 API)。允许开发者更灵活地组织和重用组件逻辑。它使用函数而不是选项对象来组织组件的代码,使得代码更具可读性和维护性。

  2. 多根组件。可以直接在 template 中使用多个根级别的元素,而不需要额外的包装元素。这样更方便地组织组件的结构。

  3. 引入了 Teleport(传送)。可以将组件的内容渲染到指定 DOM 节点的新特性。一般用于创建全局弹窗和对话框等组件。

  4. 响应式系统升级。从 defineProperty 升级到 ES2015 原生的 Proxy,不需要初始化遍历所有属性,就可以监听新增和删除的属性。

  5. 编译优化。重写了虚拟 DOM,提升了渲染速度。diff 时静态节点会被直接跳过。

  6. 源码体积优化。移除了一些非必要的特性,如 filter,一些新增的模块也将会被按需引入,减小了打包体积。

  7. 打包优化。更强的 Tree Shaking,可以过滤不使用的模块,没有使用到的组件,比如过渡(transition)组件,则打包时不会包含它。

Vue 3 移除了哪些特性

  • 移除了过滤器 filter,可以使用 computed 或函数代替

    filter 在 Vue 2 的用法:

    <template><p>{{ accountBalance | currencyUSD }}</p>
    </template><script>export default {data() {return {accountBalance: "99",}},filters: {currencyUSD(value) {return "$" + value},},}
    </script>
    
  • 移除了 .native .sync 修饰符

  • 移除了 $listeners

  • 移除了 EventBus 的相关属性:$on、$off 和 $once,可以使用第三方库代替,比如 mitt

  • 移除了 $children,可以使用 ref 代替

  • ...

为什么 Vue 3.x 采用了 Proxy 抛弃了 Object.defineProperty() ?

  • Proxy 可以代理任何对象,包括数组,而 Vue 2 中是通过重写数组的以下七种方法实现的。

    • push()(将一个或多个元素添加到数组的末尾,并返回该数组的新长度)

    • pop()(移除并返回数组的最后一个元素)

    • unshift()(将一个或多个元素添加到数组的开头,并返回该数组的新长度)

    • shift()(移除并返回数组的第一个元素)

    • splice()(删除数组中的一个或多个元素,并将其返回)

    • sort()(对数组进行排序)

    • reverse()(对数组进行反转)

  • Proxy 可以直接监听整个对象而非属性,而 Object.defineProperty() 只能先遍历对象属性再去进行监听。相比之下 Proxy 更加简洁,更加高效,更加安全。

  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的。

    const cat = {name: "Tom",
    }const myCat = new Proxy(cat, {get(target, property) {console.log(`我的 ${property} 被读取了`)return property in target ? target[property] : undefined},set(target, property, value) {console.log(`我的 ${property} 被设置成了 ${value}`)target[property] = valuereturn true},
    })myCat.name // expected output: 我被读取了:name
    myCat.name = "Kitty" // expected output: 我的 name 被设置成了 Kitty
    
  • Object.defineProperty() 的本质是在一个对象上定义一个新属性,或者修改一个现有属性。

    const cat = {name: "Tom",
    }Object.defineProperty(cat, "name", {get() {console.log(`我被读取了`)},set(value) {console.log(`我被设置成了 ${value}`)},
    })cat.name // expected output: 我被读取了
    cat.name = "Kitty" // expected output: 我被设置成了 Kitty
    
  • 而 Proxy 天生用于代理一个对象,它有 13 种基本操作的拦截方法,是 Object.defineProperty() 不具备的。

    • apply()(拦截函数的调用)

    • construct()(拦截构造函数的调用)

    • defineProperty()(拦截属性的定义)

    • deleteProperty()(拦截属性的删除)

    • get()(拦截对象属性的读取)

    • getOwnPropertyDescriptor()(拦截对象属性的描述)

    • getPrototypeOf()(拦截对象的原型)

    • has()(拦截对象属性的检查)

    • isExtensible()(拦截对象是否可扩展的检查)

    • ownKeys()(拦截对象的属性列表)

    • preventExtensions()(拦截对象是否可扩展的设置)

    • set()(拦截对象属性的设置)

    • setPrototypeOf()(拦截对象的原型的设置)

Vue 是如何实现数据双向绑定的?v-model 的原理?

Vue 组件可以通过使用 v-model 指令以实现双向绑定。v-model 是 vue 的一个语法糖,它用于监听数据的改变并将数据更新。以 input 元素为例:

<el-input v-model="foo" />

其实就等价于

<input :value="searchText" @input="searchText = $event.target.value" />

如何在组件中实现 v-model ?

在 Vue 2 组件中实现 v-model,只需定义 model 属性即可。

export default {model: {prop: "value", // 属性event: "input", // 事件},
}

在 Vue 3 组合式 API 实现 v-model,需要定义 modelValue 参数,和 emits 方法。

defineProps({modelValue: { type: String, default: "" },
})const emits = defineEmits(["update:modelValue"])function onInput(val) {emits("update:modelValue", val)
}

当数据改变时,Vue 是如何更新 DOM 的?(Diff 算法和虚拟 DOM)

当我们修改了某个数据时,如果直接重新渲染到真实 DOM,开销是很大的。Vue 为了减少开销和提高性能采用了 Diff 算法。当数据发生改变时,Observer 会通知所有 WatcherWatcher 就会调用 patch() 方法(Diff 的具体实现),把变化的内容更新到真实的 DOM,俗称打补丁

Diff 算法会对新旧节点进行同层级比较,当两个新旧节点是相同节点的时候,再去比较他们的子节点(如果是文本则直接更新文本内容),逐层比较然后找到最小差异部分,进行 DOM 更新。如果不是相同节点,则删除之前的内容,重新渲染。

逐层比较

patch() 方法先根据真实 DOM 生成一颗虚拟 DOM,保存到变量 oldVnode,当某个数据改变后会生成一个新的 Vnode,然后 Vnode 和 oldVnode 进行对比,发现有不一样的地方就直接修改在真实 DOM 上,最后再返回新节点作为下次更新的 oldVnode

什么是虚拟 DOM?有什么用?

虚拟 DOM(Virtual DOM)就是将真实 DOM 的主要数据抽取出来,并以对象的形式表达,用于优化 DOM 操作。虚拟 DOM 的主要目的是提高性能和减少实际 DOM 操作的次数,从而改善用户界面的渲染速度和响应性。

比如真实 DOM 如下:

<div id="hello"><h1>123</h1>
</div>

对应的虚拟 DOM 就是(伪代码):

const vnode = {type: "div",props: {id: "hello",},children: [{type: "h1",innerText: "123",},],
}

Vue 中的 key 有什么用?

  • 在 Vue 中,key 被用来作为 VNode 的唯一标识。

  • key 主要用在虚拟 DOM Diff 算法,在新旧节点对比时作为识别 VNode 的一个线索。如果新旧节点中提供了 key,能更快速地进行比较及复用。反之,Vue 会尽可能复用相同类型元素。

    <ul><li v-for="item in items" :key="item.id">{{ item.name }}</li>
    </ul>
    
  • 手动改变 key 值,可以强制 DOM 进行重新渲染。

    <transition><span :key="text">{{ text }}</span>
    </transition>
    

watch 和 computed 分别是做什么的?有何区别?

watch 和 computed 都可以用于监听数据,区别是使用场景不同,watch 用于监听一个数据,当数据改变时,可以执行传入的回调函数:

<script setup>import { reactive, watch } from "vue"const state = reactive({ count: 0 })watch(() => state.count,(count, prevCount) => {// do something})
</script>

computed 用于返回一个新的数据,在 Vue 3.x 中会返回一个只读的响应式 ref 对象。但是可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。

<script setup>import { reactive, computed } from "vue"const state = reactive({ numA: 1, numB: 2 })const plusOne = computed(() => state.numA + state.numB)console.log(plusOne.value) // 3
</script>

有些人会提到 computed 支持缓存,不支持异步,也是和 watch 的区别。

但这里要告诉大家的是,computed 本身的设计就是为了计算,而非异步的获取一个数据,详情请参考官网。

至于缓存,这同样属于 computed 的特性,它支持缓存,这是和调用普通函数的区别,而不应该和 watch 进行比较,watch 本身用于监听数据变化,在根本上不存在缓存的概念。

Vue 3 对 diff 算法进行了哪些优化

在 Vue 2 中,每当数据发生变化时,Vue 会创建一个新的虚拟 DOM 树,并对整个虚拟 DOM 树进行递归比较,即使其中大部分内容是静态的,最后再找到不同的节点,然后进行更新。

Vue 3 引入了静态标记的概念,通过静态标记,Vue 3 可以将模板中的静态内容和动态内容区分开来。这样,在更新过程中,Vue 3 只会关注动态部分的比较,而对于静态内容,它将跳过比较的步骤,从而避免了不必要的比较,提高了性能和效率。

<div><!-- 需静态提升 --><div>foo</div><!-- 需静态提升 --><div>bar</div><div>{{ dynamic }}</div>
</div>

Vue 实例的生命周期钩子都有哪些?

生命周期钩子是指一个组件实例从创建到卸载(销毁)的全过程,例如,设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。在这个过程中会运行一些叫做生命周期钩子的函数,从而可以使开发者们在不同阶段处理不同的业务。

Vue 2 和 Vue 3 选项式 API 的钩子大致是一样的,有以下钩子:

  • beforeCreate

    实例初始化之前,$el 和 data 都为 undefined

  • created

    实例创建完成,data 已经绑定。但 $el 不可用。

  • beforeMount

    将 <template> 和 data 生成虚拟 DOM 节点,可以访问到 $el,但还没有渲染到 html 上。

  • mounted

    实例挂载完成,渲染到 html 页面中。

  • beforeUpdate

    data 更新之前,虚拟 DOM 重新渲染之前。

  • updated

    由于 data 更新导致的虚拟 DOM 重新渲染之后。

  • beforeDestroy(Vue 2) | beforeUnmount(Vue 3)

    实例销毁之前(实例仍然可用)。

  • destroyed(Vue 2) | beforeUnmount(Vue 3)

    实例销毁之后。所有的事件监听器会被移除,所有的子实例也会被销毁,但 DOM 节点依旧存在。该钩子在服务器端渲染期间不被调用。

  • activated

    keep-alive 专用,实例被激活时调用。

  • deactivated

    keep-alive 专用,实例被移除时调用。

  • errorCaptured

    在捕获了后代组件传递的错误时调用。

第一次页面加载会触发这四个钩子:

  • beforeCreate

  • created

  • beforeMount

  • mounted

Vue 3 组合式 API 有以下钩子:

  • onBeforeMount()

    在组件被挂载之前被调用。

  • onMounted()

    在组件挂载完成后执行。

  • onBeforeUpdate()

    在组件即将因为响应式状态变更而更新其 DOM 树之前调用。

  • onUpdated()

    在组件因为响应式状态变更而更新其 DOM 树之后调用。

  • onBeforeUnmount()

    在组件实例被卸载之前调用。

  • onUnmounted()

    在组件实例被卸载之后调用。相当于 Vue 2 的 destroyed

  • onErrorCaptured()

    在捕获了后代组件传递的错误时调用。

  • onRenderTracked()

    当组件渲染过程中追踪到响应式依赖时调用。只在开发环境生效。

  • onRenderTriggered()

    当响应式依赖的变更触发了组件渲染时调用。只在开发环境生效。

  • onActivated()

    keep-alive 专用,当组件被插入到 DOM 中时调用。

  • onDeactivated()

    keep-alive 专用,当组件从 DOM 中被移除时调用。

  • onServerPrefetch()

    在组件实例在服务器上被渲染之前调用。只在 SSR 模式下生效。

nextTick 的使用场景和原理

使用场景

nextTick 是在下次 DOM 更新循环结束之后执行的一个方法。一般在修改数据之后使用这个方法操作更新后的 DOM。

export default {data() {return {message: "Hello Vue!",}},methods: {example() {// 修改数据this.message = "changed"// DOM 尚未更新this.$nextTick(() => {// DOM 现在更新了console.log("DOM 现在更新了")})},},
}

原理

在 Vue2 当中,nextTick 可以理解为就是收集异步任务到队列当中并且开启异步任务去执行它们。它可以同时收集组件渲染的任务,以及用户手动放入的任务。组件渲染的任务是由 watcher 的 update 触发,并且将回调函数包装为异步任务,最后推到 nextTick 的队列里,等待执行。

而在 Vue3 当中,nextTick 则是利用 promise 的链式调用,将用户放入的回调放在更新视图之后的 then 里面调用,用户调用多少次 nextTick,就接着多少个 then。

为什么 Vue 组件中的 data 必须是函数?

因为在 Vue 中组件是可以被复用的,组件复用其实就是创建多个 Vue 实例,实例之间共享 prototype.data 属性,当 data 的值引用的是同一个对象时,改变其中一个就会影响其他组件,造成互相污染,而改用函数的形式将数据 return 出去,则每次复用都是崭新的对象。

这里我们举个例子:

function Component() {}Component.prototype.data = {name: "vue",language: "javascript",
}const A = new Component()
const B = new Component()A.data.language = "typescript"console.log(A.data) // { name: 'vue', language: 'typescript' }
console.log(B.data) // { name: 'vue', language: 'typescript' }

此时,A 和 B 的 data 都指向了同一个内存地址,language 都变成了 'typescript'。

我们改成函数式的写法,就不会有这样的问题了。

function Component() {this.data = this.data()
}Component.prototype.data = function () {return { name: "vue", language: "javascript" }
}const A = new Component()
const B = new Component()A.data.language = "typescript"console.log(A.data) // { name: 'vue', language: 'typescript' }
console.log(B.data) // { name: 'vue', language: 'javascript' }

所以组件的 data 选项必须是一个函数,该函数返回一个独立的拷贝,这样就不会出现数据相互污染的问题。

Vue 项目中做过哪些性能优化?

  • UI 库按需加载,减小打包体积,以 ElementUI 为例:

    // main.js
    import { Button, Select } from "element-ui"Vue.use(Button)
    Vue.use(Select)
    
  • 路由按需加载

    // router.js
    export default new VueRouter({routes: [{ path: "/", component: () => import("@/components/Home") },{ path: "/about", component: () => import("@/components/About") },],
    })
    
  • 组件销毁后把同时销毁全局变量和移除事件监听和清除定时器,防止内存泄漏

    beforeDestroy() {clearInterval(this.timer)window.removeEventListener('resize', this.handleResize)
    },
    
  • 合理使用 v-if 和 v-show 使用

Vue 和 React 的区别?

Composition API(组合式 API)与 Options API(选项式 API)有什么区别?

  • Options API 会将组件中的同一逻辑相关的代码拆分到不同选项,比如 datapropsmethods 等,而使用 Composition API 较为灵活,开发者可以将同一个逻辑的相关代码放在一起。

  • Composition API 通过 Vue 3.x 新增的 setup 选项进行使用,该选项会在组件创建之前执行,第一个参数 props,第二个参数 context,return 的所有内容都会暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板。

  • Composition API 上的生命周期钩子与 Options API 基本相同,但需要添加前缀 on,比如 onMountedonUpdated 等。

v-for 和 v-if 可以同时使用吗?

可以同时使用,但不推荐,具体原因参考官方说明。

在 Vue 3 中,当 v-if 和 v-for 同时存在于一个节点上时,v-if 比 v-for 的优先级更高,此时 v-if 无法访问 v-for 中的对象,在 Vue 2 中相反。

当确实需要条件遍历渲染的话,有以下几个方法:

  • 使用数组的 fitler 过滤
<li v-for="todo in todos.filter(todo => !todo.isDone)">{{ todo.name }}</li>

使用数组的 filter 的方法可以提前对不需要的数据进行过滤,根源上解决这个问题。

  • 使用 v-show 代替
<li v-for="todo in todos" v-show="!todo.isDone">{{ todo.name }}</li>

v-show 和 v-if 都可以用于隐藏某个元素,但 v-if 用于决定是否渲染,而 v-show 则使用 display 属性决定是否显示。此时可以避免 v-if 和 v-for 同时使用造成的的渲染问题。

  • 添加额外的标签
<template v-for="todo in todos"><li v-if="!todo.isComplete">{{ todo.name }}</li>
</template>

添加额外的标签,根据层级的不同,可以自己决定 v-if 和 v-for 的优先级,这种方法更加灵活也更容易理解,但会有更深的代码结构。

总结

就祝大家都能找到一份满意的工作。

前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

相关文章:

Vue 3 常见面试题汇总

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 前言 最近两年许多大厂都在实行“降本增效”、“优化组织架构”&#xff0c;然后“为社会输送了大量人才”&#xff0c;今年&#xff08;2023&#xff…...

Docker是什么?详谈它的框架、使用场景、优势

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、什么是 Docker&#xff1f; 二、Docker 的架构 1、Docker客户端 2、Docker守护进程 3、Docker镜像 4、Docker容器 5、Docker…...

neo4j

UNWIND 将列表里的值展开 CREATE (N0:Person {name: Anders}) CREATE (N1:Person {name: Becky}) CREATE (N2:Person {name: Cesar}) CREATE (N3:Person {name: Dilshad}) CREATE (N4:Person {name: George}) CREATE (N5:Person {name: Filipa})CREATE (N0)-[:KNOWS]->(N3)…...

【项目 计网5】 4.15 TCP通信实现(服务器端)4.16 TCP通信实现(客户端)

文章目录 4.15 TCP通信实现&#xff08;服务器端&#xff09;4.16 TCP通信实现&#xff08;客户端&#xff09; 4.15 TCP通信实现&#xff08;服务器端&#xff09; // TCP 通信的服务器端// TCP 通信的服务器端 #include <stdio.h> #include <arpa/inet.h> #incl…...

windows可视化界面管理服务器上的env文件

需求&#xff1a;在 Windows 环境中通过可视化界面编辑位于 Linux 主机上的 env 文件的情况&#xff0c;我现在环境是windows环境&#xff0c;我的env文件在linux的192.168.20.124上&#xff0c;用户是op&#xff0c;密码是op&#xff0c;文件绝对路径是/home/op/compose/env …...

自然语言处理在智能客服和聊天机器人中的应用

文章目录 1. 引言2. NLP基础2.1 词法分析2.2 语法分析2.3 语义理解2.4 情感分析 3. 智能客服中的应用3.1 自动问答3.2 意图识别3.3 情感分析与情绪识别 4. 聊天机器人中的应用4.1 对话生成4.2 上下文理解 5. 技术原理与挑战5.1 语言模型5.2 数据质量和多样性5.3 上下文理解 6. …...

为什么不建议使用@Async注解创建线程

1 前言 在很久很久之前&#xff0c;我有一段痛苦的记忆。那种被故障所驱使的感觉&#xff0c;在我脑海里久久无法驱散。 原因无它&#xff0c;有小伙伴开启了线程池的暴力使用模式。没错&#xff0c;就是下面这篇文章。 夺命故障 ! 炸出了投资人&#xff01; 我有必要简单的…...

更新Ubuntu18.04上的CUDA和GCC

问题&#xff1a; 有一台服务器的GPU是1080&#xff0c;有八张卡&#xff0c;已经好久没有人用了。cuda版本是10.1,我现在拿来复现一些论文的模型&#xff0c;经常遇到版本依赖问题&#xff0c;报错Driver is too old。所以要更新一下驱动。遇到的主要问题是gcc版本也太低了&am…...

算法通过村第6关【青铜】| 如何通过中序和后序遍历恢复二叉树

中序&#xff1a;3 4 8 6 7 5 2 1 10 9 11 15 13 14 12 后序&#xff1a;8 7 6 5 4 3 2 10 15 14 13 12 11 9 1 通过这两个遍历顺序恢复二叉树 首先我们知道中序遍历顺序左中右&#xff0c;后序遍历顺序左右中 第一步&#xff1a; 由后序遍历确定根结点为1 > 由中序遍历…...

高斯牛顿法和LM算法异同示例

LM&#xff08;Levenberg-Marquardt&#xff09;算法和高斯牛顿&#xff08;Gauss-Newton&#xff09;算法是两种用于非线性最小二乘问题的优化算法&#xff0c;它们也有一些相似之处&#xff1a; 迭代优化&#xff1a;LM算法和高斯牛顿算法都使用迭代的方式来优化参数值&#…...

奥威BI财务数据分析方案:只做老板想看的

奥威BI财务数据分析方案是一套从老板的视角出发&#xff0c;做老板想看的财务数据分析报表&#xff0c;帮助老板更好地了解公司的财务状况和经营绩效的综合性智能财务数据分析方案&#xff0c;可实现财务数据分析可视化、灵活自主性&#xff0c;随时为老板提供最为直观的财务数…...

opencv进阶19-基于opencv 决策树cv::ml::DTrees 实现demo示例

opencv 中创建决策树 cv::ml::DTrees类表示单个决策树或决策树集合&#xff0c;它是RTrees和 Boost的基类。 CART是二叉树&#xff0c;可用于分类或回归。对于分类&#xff0c;每个叶子节点都 标有类标签&#xff0c;多个叶子节点可能具有相同的标签。对于回归&#xff0c;每…...

Unity通过TCP/IP协议进行通信

uinty项目中需要与C编写的硬件进行通信&#xff0c;因此采用TCP/IP协议进行通信&#xff0c;主要实现了与服务器的连接、通信内容的发送以及断开连接等功能。 根据确定好的协议格式&#xff0c;编写需要发送的内容&#xff0c;将其转为字节流&#xff08;byte[]&#xff09;通过…...

基于VuePress搭建知识库

我这边需要搭建一个运维知识库&#xff0c;将项目的方方面面记录下来&#xff0c;方便新手接手运维。 准备环境 Nginx 1.19.0VuePress 1.xMinio RELEASE.2022-02-16T00-35-27Zvuepress-theme-vdoing主题 安装VuePress 根据官网步骤即可 # 创建目录 mkdir vuepress-starter…...

odoo安装启动遇到的问题

问题&#xff1a;在第一次加载odoo配置文件的时候&#xff0c;启动失败 方法&#xff1a; 1、先检查odoo.conf的内容&#xff0c;尤其是路径 [options] ; This is the password that allows database operations: ; admin_passwd admin db_host 127.0.0.1 db_port 5432 d…...

【Flink】Flink提交流程

我们通常在学习的时候需要掌握大数据组件的原理以便更好的掌握这个大数据组件&#xff0c;Flink实际生产开发过程中最常见的就是提交到yarn上进行调度&#xff0c;模式使用的Per-Job模式&#xff0c;下面我们就给大家讲下Flink提交Per-Job任务到yarn上的流程&#xff0c;流程图…...

哪种英特尔实感设备适合您?

原文链接 https://www.intelrealsense.com/which-device-is-right-for-you/ 无论您是深度和跟踪硬件的新手&#xff0c;还是经验丰富的专业人士&#xff0c;确定我们提供的众多英特尔实感产品中哪些产品适合您的项目仍然是一项挑战。在这篇文章中&#xff0c;我们将讨论英特尔…...

C++11的四种强制类型转换

目录 语法格式 static_cast(静态转换) dynamic_cast(动态转换) const_cast&#xff08;常量转换&#xff09; reinterpret_cast(重解释) 语法格式 cast-name <typename> (expression) 其中cast-name为static_cast、dynamic_cast、const_cast 和 reinterpret_cast之一…...

分布式事务(4):两阶段提交协议与三阶段提交区别

1 两阶段提交协议 两阶段提交方案应用非常广泛&#xff0c;几乎所有商业OLTP数据库都支持XA协议。但是两阶段提交方案锁定资源时间长&#xff0c;对性能影响很大&#xff0c;基本不适合解决微服务事务问题。 缺点&#xff1a; 如果协调者宕机&#xff0c;参与者没有协调者指…...

React源码解析18(9)------ 实现多节点渲染【修改beginWork和completeWork】

摘要 目前&#xff0c;我们已经实现了单节点的&#xff0c;beginWork&#xff0c;completeWork&#xff0c;diff流程。但是对于多节点的情况&#xff0c;比如: <div><span></span><span></span> </div>这种情况&#xff0c;我们还没有处…...

【GUI】基于开关李雅普诺夫函数的非线性系统稳定(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Redis 缓存满了怎么办?

引言 Redis 缓存使用内存来保存数据&#xff0c;随着需要缓存的数据量越来越大&#xff0c;有限的缓存空间不可避免地会被写满。此时&#xff0c;应该怎么办&#xff1f;本篇文章接下来就来聊聊缓存满了之后的数据淘汰机制。 值得注意的是&#xff0c;在 Redis 中 过期策略 和…...

Grafana 安装配置教程

Grafana 安装配置教程 一、介绍二、Grafana 安装及配置2.1 下载2.2 安装2.2.1 windows安装 - 图形界面2.2.2 linux安装 - 安装脚本 三、Grafana的基本配置3.1 登录3.2 Grafana设置中文 四、grafana基本使用 一、介绍 Grafana是一个通用的可视化工具。对于Grafana而言&#xff0…...

【Linux】临界资源和临界区

目录 一、临界资源 二、如何实现对临界资源的互斥访问 1、互斥量 2、信号量 3、临界区 三、临界区 四、进程进入临界区的调度原则 一、临界资源 概念&#xff1a;临界资源是一次仅允许一个进程使用的共享资源&#xff0c;如全局变量等。 二、如何实现对临界资源的互斥访问 …...

拓扑排序Topological sorting/DFS C++应用例题P1113 杂务

拓扑排序 拓扑排序可以对DFS的基础上做变更从而达到想要的排序效果。因此&#xff0c;我们需要xy准备&#xff0c;vis数组记录访问状态&#xff0c;每一个任务都可以在dfs的过程中完成。 在使用拓扑排序方法时一些规定&#xff1a; 通常使用一个零时栈不会直接输出排序的节点…...

基于jenkins构建生成CICD环境

目录 一、安装配置jenkins 1、环境配置 2、软件要求 3、jdk安装&#xff08;我是最小化安装&#xff0c;UI自带java要先删除rm -rf /usr/local/java 4、安装jenkins-2.419-1.1 二、Jenkins配置 1、修改jenkins初始密码 2、安装 Jenkins 必要插件 3、安装 Publish Over SS…...

在线图片怎么转换成PDF?在线图片转换成PDF步骤介绍

文件格式要转化不知道怎么办?想要网上下载文件格式转换软件&#xff0c;但是却不知道下载哪个好?今天小编小编就给大家分享一下靠谱的小圆象PDF转换器工具&#xff0c;想知道这款软件好不好用?在线图片怎么转换成PDF?那就进来看看吧。 在线图片怎么转换成PDF 小圆象PDF转换…...

Linux共享库基础及实例

共享库是将库函数打包成一个可执行文件&#xff0c;使得其在运行时可以被多个进程共享。 目标库 回顾下构建程序的一种方式&#xff1a; 将每个源文件编译成目标文件&#xff0c;再通过链接器将这些目标文件链接组成一个可执行程序。 gcc -g -c prog.c mod1.c mod2.c gcc -g …...

java八股文面试[java基础]——final 关键字作用

为什么局部内部类和匿名内部类只能访问final变量&#xff1a; 知识来源 【基础】final_哔哩哔哩_bilibili...

Redis 分布式锁存在什么问题 ?如何解决 ?

目录 1. 如何实现分布式锁 2. Redis 分布式锁存在什么问题 2.1 解决死锁问题 2.2 解决锁误删问题 1. 如何实现分布式锁 Redis 天生就可以作为一个分布式系统来使用&#xff0c;所以它实现的锁都是分布式锁。 Redis 可以通过 setnx&#xff08;set if not exists&#xff09…...

手机建设银行网站进不去/免费发布产品信息的网站

Java语言基本语法 一、标识符和关键字 标识符 在java语言中&#xff0c;用来标志类名、对象名、变量名、方法名、类型名、数组名、包名的有效字符序列&#xff0c;称为“标识符”&#xff1b;标识符由字母、数字、下划线、美元符号组成&#xff0c;且第一个字符不能是数字&…...

网站的运营与维护/免费申请网站com域名

网页的组成&#xff1a; 一般由HTML&#xff0c;JavaScript&#xff0c;CSS三部分组成 HTML相当于一个房间的结构&#xff0c;CSS相当于房间的样式&#xff08;装修&#xff09;&#xff0c;JavaScript相当于功能&#xff08;电器&#xff09; 常见HTML标签: 1. <div>…...

365房产南京网站/crm网站

使用网站服务器的站长很多&#xff0c;也出现一些很常见的问题。比如&#xff0c;大多数站长可能会遇到这样的情况&#xff0c;服务器运行一段时间后会出现卡顿&#xff0c;访问缓慢甚至是死机无法连接这&#xff0c;种情况对于网站优化来说是非常严重的打击。大多数站长对于服…...

甘肃 政府 网站建设/百度人工在线客服

一、 linux文件系统 linux使用标准的目录结构&#xff0c;在安装的时候&#xff0c;安装程序就已经为用户创建了文件系统和完整而固定的目录组成形式&#xff0c;并指定了每个目录的作用和其中的文件类型。 文件系统树状结构如下&#xff1a; / 根目录 ┏━━━┳━━━┳━━…...

有哪些做兼职的设计网站有哪些工作/百度网站排名怎么提高

UIGlossyButton https://github.com/waterlou/UIGlossyButton Feature create standard iPhone buttons without any image 创建出标准的iPhone按钮,不需要你添加任何的图片easy to embed into any project, two files are needed 嵌入到你的项目中去非常的简单,你只需要两个文…...

做网站不用tomcat行吗/chrome浏览器官网入口

任务一 •在Ubuntu中完成 http://www.cnblogs.com/rocedu/p/5087623.html 中的作业 •提交运行结果截图 了解学习openssl&#xff1a; OpenSSL简介 OpenSSL是一个SSL协议的开源实现&#xff0c;采用C语言作为开发语言&#xff0c;具备了跨平台的能力&#xff0c;支持Unix/Linux…...