前端面試專欄-主流框架:13.vue3組件通信與生命周期

🔥 歡迎來到前端面試通關指南專欄!從js精講到框架到實戰,漸進系統化學習,堅持解鎖新技能,祝你輕松拿下心儀offer。
前端面試通關指南專欄主頁
前端面試專欄規劃詳情在這里插入圖片描述

Vue3組件通信與生命周期深度解析

在Vue3的開發體系中,組件通信與生命周期機制是構建高效、可維護應用的關鍵。掌握這些核心知識,能幫助開發者更好地組織代碼結構,實現組件間的協同工作。接下來,我們將深入剖析Vue3組件通信的多種方式以及組件生命周期的各個階段。

一、Vue3組件通信方式

1.1 Props與Emits

Props和Emits是Vue組件間通信的兩個核心機制,構成了父子組件數據交互的基礎模式。

Props詳解

Props是單向數據流的實現方式,父組件通過屬性綁定的方式將數據傳遞給子組件。在Vue 3的<script setup>語法中,使用defineProps宏來聲明和驗證props:

<template><div class="article-card"><h2>{{ title }}</h2><p v-if="description">{{ description }}</p><!-- 使用默認值 --><span class="views">{{ views }}次瀏覽</span></div>
</template><script setup>
const props = defineProps({// 必傳的字符串類型title: {type: String,required: true,validator: value => value.length <= 50  // 自定義驗證},// 可選的對象類型meta: {type: Object,default: () => ({})},// 帶默認值的數字views: {type: Number,default: 0},// 可選描述description: String  // 簡寫形式
});
</script>
Emits詳解

Emits允許子組件向父組件發送自定義事件,實現子到父的通信。在Vue 3中建議使用defineEmits進行明確的事件聲明:

<template><div class="search-box"><input v-model="keyword" @keyup.enter="submitSearch"placeholder="請輸入關鍵詞..."/><button @click="clearInput">清空</button></div>
</template><script setup>
import { ref } from 'vue';const emit = defineEmits({// 帶驗證的事件search: (payload) => {if (!payload || payload.length < 2) {console.warn('搜索關鍵詞至少2個字符');return false;}return true;},// 簡單事件clear: null
});const keyword = ref('');const submitSearch = () => {emit('search', keyword.value.trim());
};const clearInput = () => {keyword.value = '';emit('clear');
};
</script>
完整交互示例

父組件完整使用示例:

<template><div class="app-container"><ArticleCard:title="article.title":description="article.desc":views="article.views"@read-more="handleReadMore"/><SearchBox@search="handleSearch"@clear="searchText = ''"/><p>當前搜索: {{ searchText }}</p></div>
</template><script setup>
import { ref } from 'vue';
import ArticleCard from './ArticleCard.vue';
import SearchBox from './SearchBox.vue';const article = ref({title: 'Vue 3組件通信指南',desc: '詳細介紹各種組件通信方式',views: 1024
});const searchText = ref('');const handleReadMore = (articleId) => {console.log(':', articleId);// 導航到詳情頁...
};const handleSearch = (keyword) => {searchText.value = keyword;// 執行搜索邏輯...
};
</script>

最佳實踐提示:

  1. 始終為props定義明確的類型和驗證規則
  2. 復雜對象props建議使用函數返回默認值
  3. 事件名建議使用kebab-case命名
  4. 重要事件應該添加參數驗證

1.2 依賴注入(provide/inject)

provideinject是Vue提供的一對API,用于實現組件樹的跨層級通信,特別適合解決"prop逐層透傳"的問題,讓數據可以在祖先組件和后代組件之間直接傳遞,而不需要經過中間每一層的組件。

工作原理
  1. 提供數據(provide):在祖先組件中調用provide函數,可以提供一個鍵值對,鍵是一個字符串標識符,值是要傳遞的數據。
  2. 注入數據(inject):在后代組件中調用inject函數,通過相同的鍵名來獲取祖先組件提供的數據。
基礎用法示例

在祖先組件中使用provide提供數據:

<template><div><!-- 這是一個包含子組件的祖先組件 --><Children /></div>
</template><script setup>
import { provide } from 'vue';
import Children from './Children.vue';// 提供靜態數據
provide('globalData', '這是全局數據');// 也可以提供響應式數據
const count = ref(0);
provide('countData', count);
</script>

在后代組件中通過inject獲取數據:

<template><div><!-- 顯示從祖先組件注入的數據 --><p>注入的數據: {{ globalData }}</p><p>注入的響應式數據: {{ countData }}</p><button @click="countData++">增加計數</button></div>
</template><script setup>
import { inject } from 'vue';// 注入靜態數據
const globalData = inject('globalData');// 注入響應式數據
const countData = inject('countData');
</script>
高級用法
  1. 默認值設置
const value = inject('someKey', '默認值');
  1. 工廠函數
const value = inject('someKey', () => new ExpensiveClass());
  1. 修改權限控制(建議配合readonly使用):
provide('readOnlyData', readonly(someData));
使用場景
  1. 全局配置(如主題、語言)
  2. 共享用戶登錄狀態
  3. 表單組件中傳遞表單實例
  4. 復雜組件庫的實現(如Tree、Menu組件)
注意事項
  1. 盡量使用Symbol作為鍵名避免命名沖突
  2. 響應式數據需要保持引用一致
  3. 過度使用可能導致組件間耦合度增加

1.3 Vuex與Pinia

在Vue.js應用開發中,隨著項目規模擴大,組件間的狀態共享和通信會變得復雜。這時候就需要使用狀態管理工具來集中管理應用狀態。Vuex是Vue的官方狀態管理庫,而Pinia則是最新的推薦解決方案,具有更簡潔的API和TypeScript支持。

主要特點對比
  1. Vuex
  • 核心概念:state、mutations、actions、getters
  • 嚴格的同步修改流程(必須通過mutation修改state)
  • 適用于復雜的應用場景
  • 需要定義modules來組織大型應用
  1. Pinia
  • 更簡單的API設計
  • 支持組合式API
  • 天然支持TypeScript
  • 不需要mutations,可以直接修改state
  • 自動代碼分割
Pinia使用詳解

Pinia的基本使用分為三個步驟:

  1. 定義Store
import { defineStore } from 'pinia';// 使用defineStore定義store
// 第一個參數是store的唯一ID
export const useCounterStore = defineStore('counter', {// state使用函數返回初始狀態state: () => ({count: 0,title: 'My Counter'}),// actions定義業務邏輯actions: {increment() {this.count++;  // 直接修改state},async fetchData() {// 可以包含異步操作const response = await fetch('/api/data');// ...}},// getters相當于計算屬性getters: {doubleCount: (state) => state.count * 2}
});
  1. 在組件中使用Store
<template><div><h2>{{ counterStore.title }}</h2><p>當前計數: {{ counterStore.count }}</p><p>雙倍計數: {{ counterStore.doubleCount }}</p><button @click="counterStore.increment">增加</button><button @click="resetCounter">重置</button></div>
</template><script setup>
import { useCounterStore } from '@/stores/counter';
import { storeToRefs } from 'pinia';// 使用store
const counterStore = useCounterStore();// 如果需要解構,使用storeToRefs保持響應性
const { title } = storeToRefs(counterStore);// 可以直接調用action
function resetCounter() {counterStore.$reset();  // 重置state
}
</script>
  1. 在main.js中安裝Pinia
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';const app = createApp(App);
app.use(createPinia());
app.mount('#app');
實際應用場景
  1. 用戶信息管理
// stores/user.js
export const useUserStore = defineStore('user', {state: () => ({userInfo: null,token: ''}),actions: {login(userData) {this.userInfo = userData;this.token = 'generated_token';localStorage.setItem('token', this.token);},logout() {this.userInfo = null;this.token = '';localStorage.removeItem('token');}}
});
  1. 購物車管理
// stores/cart.js
export const useCartStore = defineStore('cart', {state: () => ({items: [],total: 0}),actions: {addItem(product) {const existingItem = this.items.find(item => item.id === product.id);if (existingItem) {existingItem.quantity++;} else {this.items.push({...product, quantity: 1});}this.calculateTotal();},calculateTotal() {this.total = this.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);}}
});

Pinia的這些特性使它成為Vue 3應用中管理狀態的首選方案,特別是在需要處理復雜狀態邏輯、跨組件共享數據或需要良好TypeScript支持的項目中。

1.4 事件總線(mitt或tiny-emitter)

對于非父子組件之間的復雜通信場景(如跨多級組件、兄弟組件等),可以引入輕量級的第三方事件總線庫如mitt或tiny-emitter。這種方法通過發布訂閱模式實現解耦通信。下面以mitt為例詳細介紹:

安裝

首先通過npm安裝mitt庫:

npm install mitt
# 或者使用yarn
yarn add mitt
初始化事件總線

創建獨立的eventBus.js文件作為事件中心:

// src/utils/eventBus.js
import mitt from 'mitt';// 創建mitt實例
const emitter = mitt();// 可選:定義全局事件類型常量
export const EventTypes = {CUSTOM_EVENT: 'customEvent',USER_LOGIN: 'userLogin'
};export default emitter;
事件觸發(發布)

在組件A中發布事件,可傳遞任意數據:

<template><button @click="sendEvent">發送全局事件</button><button @click="sendUserInfo">發送用戶信息</button>
</template><script setup>
import emitter, { EventTypes } from '@/utils/eventBus';const sendEvent = () => {// 觸發普通事件emitter.emit(EventTypes.CUSTOM_EVENT, {timestamp: new Date(),message: '來自組件A的重要通知'});
};const sendUserInfo = () => {// 觸發帶用戶數據的事件emitter.emit(EventTypes.USER_LOGIN, {userId: 'U123456',username: '張三'});
};
</script>
事件監聽(訂閱)

在組件B中訂閱事件:

<template><div><p>收到消息: {{ message }}</p><p>用戶狀態: {{ userStatus }}</p></div>
</template><script setup>
import { ref, onUnmounted } from 'vue';
import emitter, { EventTypes } from '@/utils/eventBus';const message = ref('');
const userStatus = ref('未登錄');// 監聽自定義事件
const eventHandler = (data) => {message.value = `${data.message} (${new Date(data.timestamp).toLocaleTimeString()})`;
};// 監聽用戶登錄事件
const loginHandler = (user) => {userStatus.value = `${user.username}已登錄(ID:${user.userId})`;
};// 組件掛載時注冊監聽
emitter.on(EventTypes.CUSTOM_EVENT, eventHandler);
emitter.on(EventTypes.USER_LOGIN, loginHandler);// 組件卸載時移除監聽
onUnmounted(() => {emitter.off(EventTypes.CUSTOM_EVENT, eventHandler);emitter.off(EventTypes.USER_LOGIN, loginHandler);
});
</script>
其他用法
  1. 一次性事件
emitter.once('one-time-event', () => {console.log('只會觸發一次');
});
  1. 清除所有事件
emitter.all.clear();
  1. 類型安全(TypeScript)
type Events = {search: stringchange: number
};const emitter = mitt<Events>();
emitter.emit('search', 'query'); // OK
emitter.emit('change', 123); // OK
注意事項
  1. 建議在組件卸載時移除事件監聽,避免內存泄漏
  2. 對于大型項目,建議按模塊劃分不同的事件總線實例
  3. 事件名稱最好使用常量管理,避免拼寫錯誤
  4. 復雜場景可以考慮使用Vuex或Pinia替代

相比Vue2的EventBus,mitt更輕量(200b),且不依賴Vue實例,適合簡單的跨組件通信場景。

二、Vue3組件生命周期

2.1 組件初始化階段

  • setup:在組件創建之前執行,是Composition API的核心入口點。它取代了Vue 2.x中的datamethodscomputed等選項,統一在一個函數內進行組件邏輯的組織。主要功能包括:
    1. 初始化響應式數據(使用ref/reactive)
    2. 定義組件方法
    3. 設置計算屬性
    4. 注冊生命周期鉤子
    5. 返回模板需要訪問的數據和方法

特性說明:

  • 沒有this上下文,所有操作都通過導入的Vue API實現
  • 只能同步執行,不可使用async/await
  • 接受兩個參數:props和context(包含attrs/slots/emit等)
  • 必須返回一個對象,其屬性將暴露給模板使用

典型應用場景:

  • 組合可復用的邏輯代碼
  • 類型Script支持更好的類型推斷
  • 更清晰的邏輯組織方式

示例擴展:

<template><div><p>{{ count }}</p><button @click="increment">+1</button><p>{{ doubledCount }}</p></div>
</template><script setup>
import { ref, computed } from 'vue';// 響應式數據
const count = ref(0);// 計算方法
const doubledCount = computed(() => count.value * 2);// 組件方法
function increment() {count.value++;
}// 暴露給模板
defineExpose({count,increment
})
</script>

注意事項:

  1. <script setup>語法糖中,所有頂層綁定自動暴露給模板
  2. 需要暴露給父組件的內容需使用defineExpose
  3. 生命周期鉤子需使用專門API(如onMounted)在setup內注冊
  4. 與Options API混用時需注意執行順序問題

2.2 組件掛載階段

onBeforeMount

在組件即將掛載到DOM之前調用,此階段具有以下特點:

  1. 模板編譯已完成,但尚未轉換為實際的DOM節點
  2. 組件的$el屬性尚未生成,無法訪問DOM元素
  3. 適合執行一些與渲染無關的準備工作,如:
    • 數據預處理
    • 計算屬性的最終計算
    • 配置初始化

典型應用場景:

  • 準備渲染所需的數據
  • 設置初始狀態變量
  • 執行不依賴DOM的初始化邏輯
onMounted

在組件掛載到DOM之后調用,此階段具有以下特點:

  1. 組件已經生成真實的DOM結構
  2. 可以安全地訪問和操作DOM元素
  3. 常用于以下操作:
    • 初始化需要DOM的第三方庫(如圖表庫、地圖插件等)
    • 手動操作DOM元素(添加事件監聽器、修改樣式等)
    • 發送異步請求獲取數據
    • 執行需要測量DOM尺寸的邏輯

實際開發中的典型用法示例:

<template><div id="app"><canvas ref="chartCanvas"></canvas></div>
</template><script setup>
import { onMounted, ref } from 'vue';
import Chart from 'chart.js';const chartCanvas = ref(null);onMounted(() => {// 初始化圖表new Chart(chartCanvas.value, {type: 'bar',data: {/*...*/},options: {/*...*/}});// 獲取DOM元素尺寸const dimensions = {width: chartCanvas.value.offsetWidth,height: chartCanvas.value.offsetHeight};// 添加事件監聽window.addEventListener('resize', handleResize);
});
</script>

注意事項:

  1. onBeforeMount中不要嘗試訪問DOM,因為此時DOM還不存在
  2. 在服務器端渲染(SSR)時,onMounted不會在服務器端執行
  3. 如果需要在組件卸載時清理資源(如事件監聽器),應該在onUnmounted生命周期鉤子中進行

2.3 組件更新階段

組件更新階段是Vue響應式系統中重要的生命周期環節,當組件依賴的響應式數據發生變化時,會觸發更新流程。這一階段主要包含兩個關鍵鉤子函數:

  • onBeforeUpdate:在組件數據更新之前調用。此時Vue已經檢測到數據變化并準備更新DOM,但DOM尚未實際更新。這個鉤子常用于獲取更新前的DOM狀態或執行更新前的準備工作。

    典型應用場景:

    • 記錄組件更新前的滾動位置
    • 保存當前表單的驗證狀態
    • 執行數據變更前的最后校驗
  • onUpdated:在組件數據更新之后調用,此時DOM已經根據更新后的數據完成了重新渲染。這個鉤子適合執行依賴新DOM的操作,但要注意避免在此修改響應式數據,否則可能導致無限更新循環。

    常見使用場景:

    • 更新后自動聚焦表單元素
    • 集成第三方DOM庫(如圖表庫)
    • 執行DOM相關的測量操作
<template><div><p>當前計數:{{ count }}</p><button @click="increment">增加計數</button><div ref="messageBox" style="height:100px;overflow:auto;border:1px solid #ccc;margin-top:10px"><p v-for="msg in messages" :key="msg">{{ msg }}</p></div></div>
</template><script setup>
import { ref, onBeforeUpdate, onUpdated } from 'vue';const count = ref(0);
const messages = ref(['初始消息']);
const messageBox = ref(null);// 記錄更新前的滾動位置
let prevScrollHeight = 0;const increment = () => {count.value++;messages.value.push(`新消息 ${count.value}`);
};onBeforeUpdate(() => {console.log('[BeforeUpdate] 組件即將更新');if (messageBox.value) {prevScrollHeight = messageBox.value.scrollHeight;}
});onUpdated(() => {console.log('[Updated] 組件已完成更新');// 保持滾動位置不變if (messageBox.value) {messageBox.value.scrollTop = messageBox.value.scrollHeight - prevScrollHeight;}// 更新后自動聚焦到按鈕document.querySelector('button')?.focus();
});
</script>

示例說明:

  1. 當點擊"增加計數"按鈕時,會觸發count和messages數據的變更
  2. onBeforeUpdate鉤子會在數據變更后、DOM更新前執行,這里記錄消息容器的滾動高度
  3. Vue完成DOM更新后,onUpdated鉤子觸發,調整滾動位置保持用戶體驗一致
  4. 每次更新后自動聚焦按鈕,提升可訪問性

注意事項:

  • 更新鉤子可能在父/子組件間多次觸發,可通過條件判斷避免重復操作
  • 在onUpdated中修改數據需謹慎,可能導致無限循環
  • 對于復雜DOM操作,建議配合nextTick使用確保DOM更新完成

2.4 組件卸載階段

  • onBeforeUnmount:在組件即將卸載之前調用,主要用于執行清理工作。這是最后的機會來處理組件相關的資源釋放,常見應用場景包括:

    • 清除定時器(如setTimeout/setInterval)
    • 移除DOM事件監聽器
    • 取消網絡請求(如axios請求)
    • 關閉WebSocket連接
    • 清理第三方庫實例
      不及時清理這些資源可能導致內存泄漏,影響應用性能。
  • onUnmounted:在組件完全卸載之后調用,此時組件實例及其所有子組件都已被銷毀。通常用于:

    • 執行最終的日志記錄
    • 觸發分析事件
    • 確認資源已完全釋放
      注意此時已無法訪問DOM元素或組件實例。
<template><div v-if="show"><p>這是一個組件</p><div id="chart-container"></div>  <!-- 假設這里使用了Echarts圖表 --></div><button @click="hideComponent">隱藏組件</button>
</template><script setup>
import { ref, onBeforeUnmount, onUnmounted } from 'vue';
import * as echarts from 'echarts';  // 引入Echarts庫const show = ref(true);
const chartInstance = ref(null);  // 存儲圖表實例
const hideComponent = () => {show.value = false;
};// 模擬一個定時器
let timer = setInterval(() => {console.log('定時器運行中...');
}, 1000);// 模擬一個事件監聽
const handleResize = () => console.log('窗口大小改變');
window.addEventListener('resize', handleResize);// 初始化圖表
const initChart = () => {chartInstance.value = echarts.init(document.getElementById('chart-container'));chartInstance.value.setOption({/* 圖表配置 */});
};
initChart();onBeforeUnmount(() => {// 清理定時器clearInterval(timer);console.log('定時器已清除');// 移除事件監聽window.removeEventListener('resize', handleResize);console.log('事件監聽已移除');// 銷毀圖表實例if(chartInstance.value) {chartInstance.value.dispose();console.log('圖表實例已銷毀');}console.log('組件即將卸載,資源清理完成');
});onUnmounted(() => {console.log('組件已完全卸載');// 可以在這里發送組件卸載的埋點數據// analytics.track('ComponentUnmounted');
});
</script>

2.5 錯誤處理階段

onErrorCaptured 鉤子詳解

當組件樹中的任意后代組件拋出錯誤時,該鉤子會被觸發。它是 Vue 3 中用于構建組件級錯誤邊界的重要機制。

核心功能:

  1. 捕獲后代組件傳遞的所有錯誤(包括渲染錯誤、生命周期鉤子錯誤等)
  2. 提供錯誤對象、組件實例和錯誤來源信息
  3. 可以通過返回值控制是否繼續向上傳播錯誤

典型應用場景:

  • 全局錯誤日志收集
  • 優雅降級UI展示
  • 錯誤信息上報系統
  • 開發環境調試輔助

參數詳解:

onErrorCaptured((error, instance, info) => {// error: 錯誤對象// instance: 觸發錯誤的組件實例 // info: 錯誤來源信息字符串(如:'render function')
})

示例擴展:

<template><div><!-- 安全邊界組件 --><ErrorBoundary><ChildComponent /></ErrorBoundary><!-- 備用渲染 --><div v-if="error">組件加載失敗,請<a @click="retry">重試</a></div></div>
</template><script setup>
import { ref } from 'vue';const error = ref(null);
const retry = () => location.reload();onErrorCaptured((err) => {error.value = err;// 阻止錯誤繼續冒泡return false; // 如需繼續傳播則返回true
});
</script>

最佳實踐建議:

  1. 生產環境應配合Sentry等監控工具使用
  2. 重要業務組件建議單獨設置錯誤邊界
  3. 異步錯誤需結合async/await處理
  4. 注意避免在錯誤處理中觸發新的錯誤

錯誤傳播控制:
通過返回布爾值決定是否阻止錯誤繼續冒泡:

  • return false:阻止傳播
  • return true:允許繼續傳播
  • 未返回值:默認等同于return true

調試技巧:
在開發環境中,可以利用該鉤子快速定位組件問題:

onErrorCaptured((err, vm, info) => {console.group('[ErrorCaptured]');console.log('Component:', vm.type.__name);console.log('Info:', info); console.error(err);console.groupEnd();
});

Vue3的組件通信與生命周期機制為開發者提供了豐富且靈活的工具。通過合理運用各種通信方式,結合組件生命周期鉤子函數,能夠構建出結構清晰、交互流暢的前端應用,滿足不同業務場景的需求。在實際開發過程中,開發者應根據項目的具體情況,選擇最合適的通信和生命周期處理方式,提升開發效率與應用質量。

📌 下期預告:Vue Router與Vuex核心應用
??????:如果你覺得這篇文章對你有幫助,歡迎點贊、關注本專欄!后續解鎖更多功能,敬請期待!👍🏻 👍🏻 👍🏻
更多專欄匯總:
前端面試專欄
Node.js 實訓專欄

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86149.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86149.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86149.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

自動化交易優化網格策略

一、動態參數調整 1. 網格間距優化 - 波動率自適應&#xff1a;使用平均真實波幅&#xff08;ATR&#xff09;指標動態調整間距。例如&#xff0c;當ATR值上升20%時&#xff0c;將間距從原定的1%擴大至1.5%&#xff1b;ATR下降時則縮小間距至0.8%。可通過Python的TA-Lib庫實時計…

測試平臺ui自動化demo說明

1. 要啟動celery worker windows 開發時&#xff0c;用第二行 。&#xff08;試過&#xff0c;可以&#xff09;&#xff0c;第一行的沒試過。 celery -A myproject worker --loglevelinfo # windows電腦用下面的&#xff0c;并且settings中還要加那個solo celery -A your_p…

五大主要Token類型之字符標記Token

如大家所了解的&#xff0c;在數字化時代&#xff0c;我們每天都會與Token&#xff08;令牌&#xff09;打交道——無論是在線支付、登錄社交媒體&#xff0c;還是調用API接口&#xff0c;都離不開這一關鍵技術。 今天我們主要來學習&#xff1a;字符標記Token 在自然語言處理…

可理解性輸入:洗澡習慣

一、開場與淋浴準備 Today we’re going to learn bathroom English. Let’s get started. So the first thing we want to do. Make sure we have our towel and we’ll hang it on the towel rack before we have a shower. Because if we have a shower and then forget ou…

GO Echo框架面試題及參考答案

目錄 Echo 框架的核心結構是什么?Echo 和 Context 分別扮演什么角色? 如何創建一個 Echo 實例?簡述常見配置項。 e.Start () 與 e.StartServer () 的區別是什么? Echo 如何實現基于先后順序路由匹配? 如何注冊 GET、POST、PUT、DELETE 等不同 HTTP 方法的路由? Echo…

Java 中LinkedList 總結

406.根據身高重建隊列 力扣題目鏈接(opens new window) 假設有打亂順序的一群人站成一個隊列&#xff0c;數組 people 表示隊列中一些人的屬性&#xff08;不一定按順序&#xff09;。每個 people[i] [hi, ki] 表示第 i 個人的身高為 hi &#xff0c;前面 正好 有 ki 個身高…

大模型微調:從零到實踐,掌握AI大模型的核心技能

大模型微調&#xff1a;從零到實踐&#xff0c;掌握AI大模型的核心技能 引言 大規模語言模型&#xff08;如DeepSeek、通義千問&#xff09;的出現&#xff0c;徹底改變了自然語言處理的格局。這些模型不僅在學術界取得了突破性進展&#xff0c;在工業界也得到了廣泛應用。 …

Flutter - 原生交互 - 相冊

環境 Flutter 3.29 macOS Sequoia 15.4.1 Xcode 16.3 iOS 13.4.1 iOS 18.5 集成image_picker 在Flutter中可以使用image_picker插件實現從相冊中獲取圖片 添加插件 flutter中訪問相冊image_picker插件 flutter pub add image_pickerflutter pub getXcode工程的GenerateP…

node.js在vscode的配置

文章目錄 概要1. 使用和webstrom一樣的快捷鍵2. 讓vscode的主題變成webstrom3. 如何在 Node.js 環境下寫代碼3.1 使用 ESLint配置規則3.2 配置.vscode/settings.json 4. Prettier安裝5. 其它問題解決 概要 node.js在webstrom編輯器中可以完美使用代碼提示、錯誤提示等功能&…

Android14音頻子系統-Audio HAL分析

文章目錄 1&#xff09;概述2&#xff09;HAL的打開流程3&#xff09;HAL庫的實現(Qualcomm)4&#xff09;tinyalsa5&#xff09;數據結構6&#xff09;代碼流程 1&#xff09;概述 1、回顧HAL、tinyalsa與linux driver的關系 2、與AudioFlinger的關系 3、 1、如何判斷當前…

前端與 Spring Boot 后端無感 Token 刷新 - 從原理到全棧實踐

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有堅忍不拔之志 &#x1f390; 個人CSND主頁——Micro麥可樂的博客 &#x1f425;《Docker實操教程》專欄以最新的Centos版本為基礎進行Docker實操教程&#xff0c;入門到實戰 &#x1f33a;《RabbitMQ》…

【AI智能體】新手教程-通過 Chat SDK 搭建網頁在線客服

通過扣子搭建的智能體可以一鍵發布為 Chat SDK&#xff0c;快速部署到你的自建網站中&#xff0c;作為在線智能客服面向網站的用戶提供 AI 答疑服務。本文檔介紹通過 Chat SDK 搭建網頁版在線客服的詳細操作步驟。 場景說明 網站作為企業和組織與用戶互動的重要平臺&#xff…

flask靜態資源與模板頁面、模板用戶登錄案例

案例代碼 import flask# template_folder 模板文件夾(靜態頁面 html頁面渲染) # static_folder 靜態資源文件夾主要存放的是類似靜態數據、音頻、視頻、圖片等 app flask.Flask(__name__, static_folderstatic, template_foldertemplate)app.route(/) def index():# render_t…

【工具教程】識別PDF中文字內容,批量識別文字并保存到Excel表格中的操作步驟和方法

在日常辦公和文件管理中&#xff0c;我們常常會遇到需要處理大量 PDF 文件的情況。有時&#xff0c;為了更好地管理和查找這些文件&#xff0c;需要根據 PDF 文件中特定區域的文字內容對文件進行重命名。例如&#xff0c;在企業檔案管理中&#xff0c;合同文件可能需要根據合同…

重生學AI第十三集:初識神經網絡之Conv2d

終于該學習神經網絡的搭建了&#xff0c;開心&#xff0c;嘻嘻 學習神經網絡離不開torch.nn&#xff0c;先把他印在腦子里&#xff0c;什么是torch.nn?他是Pytorch的一個模塊&#xff0c;包含了大量構建神經網絡需要的類和方法&#xff0c;就像前面學習的torch.utils&#xf…

學習C++、QT---07(C++的權限、C++的引用)

每日一言 你解決的每一個難題&#xff0c;都是在為未來的自己解鎖新技能。 權限的講解 這邊呢我們利用銀行的一個案例來講解權限的奧秘 權限指的是public、private 、protected 就是這三種權限&#xff0c;因此有這一張表進行分清他們之間的區別和聯系 但是我們在平時的話會因…

全球化短劇平臺全棧技術架構白皮書:多區域部署、智能分發與沉浸式體驗的完整解決方案

一、全球化基礎架構深度設計 全球網絡基礎設施構建 采用多活數據中心部署模式&#xff0c;在北美&#xff08;弗吉尼亞&#xff09;、歐洲&#xff08;法蘭克福&#xff09;、亞太&#xff08;新加坡&#xff09;建立三大核心樞紐節點 構建混合CDN網絡&#xff0c;整合AWS Clo…

深入剖析 LGM—— 開啟高分辨率 3D 內容創作新時代

一、引言 在當今數字化時代&#xff0c;3D 內容創作的需求如井噴般增長&#xff0c;從游戲開發中絢麗多彩的虛擬世界&#xff0c;到影視制作里震撼人心的特效場景&#xff0c;再到工業設計中精準無誤的產品原型&#xff0c;3D 技術無處不在。然而&#xff0c;傳統 3D 內容創作…

從用戶到社區Committer:小米工程師隋亮亮的Apache Fory成長之路

Apache Fory 是一個基于JIT和零拷貝的高性能多語言序列化框架&#xff0c;實現了高效緊湊的序列化協議&#xff0c;提供極致的性能、壓縮率和易用性。在多語言序列化框架技術領域取得了重大突破&#xff0c;推動序列化技術步入高性能易用新篇章&#xff01;這一切&#xff0c;都…

【Koa系列】10min快速入門Koa

簡介 koa是基于node開發的一個服務端框架&#xff0c;功能同express&#xff0c;但更小巧簡單。 官方倉庫地址&#xff1a;https://github.com/koajs/koa 創建項目 創建文件夾nodeKoa&#xff0c;執行以下腳本 npm init -y npm i koa npm i nodemon 基礎示例 創建一個服…