React Native 接入 eCharts

React Native 圖表接入指南

概述

本文檔詳細介紹了在React Native項目中接入ECharts圖表的完整步驟,包括依賴安裝、組件配置、數據獲取、圖表渲染等各個環節。

目錄

  • 1. 環境準備
  • 2. 依賴安裝
  • 3. 圖表組件創建
  • 4. 數據獲取Hook
  • 5. 圖表配置
  • 6. 組件集成
  • 7. 國際化支持
  • 8. 最佳實踐
  • 9. 常見問題

1. 環境準備

1.1 項目要求

  • React Native 0.76.9+
  • Expo SDK 52+
  • TypeScript 5.3.3+
  • Node.js 18.18.0+

1.2 開發環境

確保已安裝以下工具:

  • Node.js 和 npm/yarn
  • React Native CLI 或 Expo CLI
  • iOS Simulator (macOS) 或 Android Emulator

2. 依賴安裝

2.1 核心依賴

# 安裝圖表核心庫
npm install echarts@^5.6.0# 安裝React Native圖表渲染器
npm install @wuba/react-native-echarts@^2.0.3# 安裝SVG支持(圖表渲染需要)
npm install react-native-svg@^15.8.0# 安裝日期處理庫(用于圖表時間軸格式化)
npm install date-fns@^4.1.0

這個過程是這樣的:

  1. ECharts 核心庫 ( echarts ) :負責所有的數據處理、圖表邏輯計算和配置項解析。它會生成一個虛擬的、與平臺無關的渲染指令。
  2. SVG 渲染器 ( SVGRenderer ) :這個渲染器來自于 @wuba/react-native-echarts 包,它的作用是接收 ECharts 核心庫生成的渲染指令,并將其轉換成 SVG 元素。
  3. React Native SVG ( react-native-svg ) :這個庫提供了在 React Native 中渲染 SVG 的能力。它會將 SVGRenderer 生成的 SVG 元素真正在原生視圖上繪制出來。
    所以,整個流程可以看作是 ECharts (邏輯) -> SVGRenderer (轉換為 SVG) -> react-native-svg (在屏幕上繪制) 。這種方式使得強大的 ECharts 庫能夠跨平臺運行在沒有原生 Canvas 和 DOM 環境的 React Native 中

2.2 可選依賴

# 如果需要健康數據(如心率圖表示例)
npm install react-native-health@^1.19.0# 如果需要更多圖表類型
npm install @types/echarts

2.3 依賴說明

依賴包版本作用
echarts^5.6.0圖表核心庫,提供豐富的圖表類型
@wuba/react-native-echarts^2.0.3React Native適配的ECharts渲染器
react-native-svg^15.8.0SVG渲染支持,圖表顯示必需
date-fns^4.1.0日期處理工具,用于時間軸格式化

3. 圖表組件創建

3.1 基礎組件結構

創建文件:app/components/HeartRateChart.tsx

import { useRef, useEffect, useMemo } from "react"
import { StyleProp, View, ViewStyle } from "react-native"
import { echarts } from "../utils/echarts" // 導入集中的 echarts 實例
import SvgChart from "@wuba/react-native-echarts/svgChart"
import { useHealthData } from "../hooks/useHealthData"
import { HealthValue } from "react-native-health"
import { format } from "date-fns"
import { ECharts } from "echarts/core"// 不再需要在此處注冊組件,已在 app/utils/echarts.ts 中集中處理interface HeartRateChartProps {style?: StyleProp<ViewStyle>
}const CHART_HEIGHT = 300
const CHART_WIDTH = 350export function HeartRateChart(props: HeartRateChartProps) {const { style } = propsconst chartRef = useRef<any>(null)const { heartRateSamples, fetchHeartRateSamples, permissionsGranted } = useHealthData({requestPermissions: true,autoFetch: false,})// 數據獲取useEffect(() => {if (permissionsGranted) {const endDate = new Date()const startDate = new Date()startDate.setDate(endDate.getDate() - 1)fetchHeartRateSamples(startDate, endDate)}}, [permissionsGranted, fetchHeartRateSamples])// 圖表配置const chartOption = useMemo(() => {if (!heartRateSamples || heartRateSamples.length === 0) {return {}}const data = heartRateSamples.map((sample: HealthValue) => [new Date(sample.startDate),sample.value,])return {tooltip: {trigger: "axis",formatter: (params: any) => {const param = params[0]const date = new Date(param.axisValue)const value = param.data[1]return `${format(date, "MM-dd HH:mm")}<br/>心率: ${value}`},},xAxis: {type: "time",axisLabel: {formatter: (value: number) => {return format(new Date(value), "HH:mm")},},},yAxis: {type: "value",name: "心率 (bpm)",min: (value: { min: number }) => Math.floor(value.min / 10) * 10,},series: [{data,type: "line",smooth: true,showSymbol: false,lineStyle: {width: 2,},},],grid: {left: "12%",right: "5%",bottom: "10%",top: "10%",},}}, [heartRateSamples])// 圖表初始化和更新useEffect(() => {let chartInstance: ECharts | undefinedif (chartRef.current && Object.keys(chartOption).length > 0) {chartInstance = echarts.init(chartRef.current, "light", {renderer: "svg",width: CHART_WIDTH,height: CHART_HEIGHT,})chartInstance.setOption(chartOption)}return () => {chartInstance?.dispose()}}, [chartOption])return (<View style={style}><SvgChart ref={chartRef} /></View>)
}

3.2 組件導出

app/components/index.ts 中添加導出:

export * from "./HeartRateChart"

4. 數據獲取Hook

4.1 創建數據Hook

創建文件:app/hooks/useHealthData.ts

import { useState, useCallback, useEffect } from "react"
import AppleHealthKit, { HealthKitPermissions, HealthValue } from "react-native-health"interface HealthDataState {stepCount: number | nullheartRateSamples: HealthValue[]isLoading: booleanerror: string | nullpermissionsGranted: boolean
}interface UseHealthDataOptions {requestPermissions?: booleanautoFetch?: boolean
}export const useHealthData = (options: UseHealthDataOptions = {}) => {const { requestPermissions = true, autoFetch = true } = optionsconst [healthData, setHealthData] = useState<HealthDataState>({stepCount: null,heartRateSamples: [],isLoading: false,error: null,permissionsGranted: false,})// 初始化 HealthKit 并請求權限const initializeHealthKit = useCallback(async () => {if (!requestPermissions) returnsetHealthData((prev) => ({ ...prev, isLoading: true, error: null }))const permissions = {permissions: {read: [AppleHealthKit.Constants.Permissions.Steps,AppleHealthKit.Constants.Permissions.HeartRate,AppleHealthKit.Constants.Permissions.StepCount,],write: [],},} as HealthKitPermissionsreturn new Promise<void>((resolve, reject) => {AppleHealthKit.initHealthKit(permissions, (error: string) => {if (error) {const errorMessage = `無法授予 HealthKit 權限: ${error}`console.error("HealthKit 權限請求失敗:", errorMessage)setHealthData((prev) => ({...prev,isLoading: false,error: errorMessage,permissionsGranted: false,}))reject(new Error(errorMessage))return}setHealthData((prev) => ({...prev,isLoading: false,permissionsGranted: true,}))resolve()})})}, [requestPermissions])// 獲取心率樣本const fetchHeartRateSamples = useCallback(async (startDate?: Date, endDate?: Date) => {if (!healthData.permissionsGranted) {const errorMsg = "HealthKit 權限未授予,無法獲取心率數據"console.error(errorMsg)throw new Error(errorMsg)}setHealthData((prev) => ({ ...prev, isLoading: true, error: null }))const heartRateOptions = {startDate: (startDate || new Date(new Date().getTime() - 24 * 60 * 60 * 1000)).toISOString(),endDate: (endDate || new Date()).toISOString(),}return new Promise<HealthValue[]>((resolve, reject) => {AppleHealthKit.getHeartRateSamples(heartRateOptions,(err: string, results: HealthValue[]) => {if (err) {const errorMessage = `獲取心率樣本時出錯: ${err}`console.error(errorMessage)setHealthData((prev) => ({...prev,isLoading: false,error: errorMessage,}))reject(new Error(errorMessage))return}setHealthData((prev) => ({...prev,heartRateSamples: results,isLoading: false,}))resolve(results)},)})},[healthData.permissionsGranted],)// 獲取所有健康數據const fetchAllHealthData = useCallback(async () => {if (!healthData.permissionsGranted) {return}try {await fetchHeartRateSamples()} catch (error) {console.error("獲取健康數據時出錯:", error)}}, [fetchHeartRateSamples, healthData.permissionsGranted])// 清除錯誤const clearError = useCallback(() => {setHealthData((prev) => ({ ...prev, error: null }))}, [])// 初始化useEffect(() => {if (requestPermissions) {initializeHealthKit().then(() => {setTimeout(() => {if (autoFetch) {fetchAllHealthData()}}, 100)}).catch((error) => {console.error("初始化 HealthKit 失敗:", error)})}}, [requestPermissions, autoFetch, initializeHealthKit, fetchAllHealthData])return {// 狀態...healthData,// 方法initializeHealthKit,fetchHeartRateSamples,fetchAllHealthData,clearError,}
}

4.2 Hook導出

app/hooks/index.ts 中添加導出:

export * from "./useHealthData"

5. 圖表配置

5.1 基礎配置

const baseChartOption = {// 提示框配置tooltip: {trigger: "axis",backgroundColor: "rgba(0, 0, 0, 0.8)",borderColor: "rgba(255, 255, 255, 0.2)",textStyle: {color: "#fff",},},// 網格配置grid: {left: "12%",right: "5%",bottom: "10%",top: "10%",containLabel: true,},// 動畫配置animation: true,animationDuration: 1000,animationEasing: "cubicOut",
}

5.2 時間軸配置

const timeAxisConfig = {xAxis: {type: "time",axisLabel: {formatter: (value: number) => format(new Date(value), "HH:mm"),color: "#666",fontSize: 12,},axisLine: {lineStyle: {color: "#ddd",},},splitLine: {show: true,lineStyle: {color: "#f0f0f0",type: "dashed",},},},
}

5.3 數值軸配置

const valueAxisConfig = {yAxis: {type: "value",name: "心率 (bpm)",nameTextStyle: {color: "#666",fontSize: 12,},axisLabel: {color: "#666",fontSize: 12,},axisLine: {lineStyle: {color: "#ddd",},},splitLine: {show: true,lineStyle: {color: "#f0f0f0",type: "dashed",},},min: (value: { min: number }) => Math.floor(value.min / 10) * 10,},
}

5.4 數據系列配置

const seriesConfig = {series: [{data: chartData,type: "line",smooth: true,showSymbol: false,lineStyle: {width: 2,color: "#ff6b6b",},areaStyle: {color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{ offset: 0, color: "rgba(255, 107, 107, 0.3)" },{ offset: 1, color: "rgba(255, 107, 107, 0.1)" },],},},},],
}

6. 組件集成

6.1 創建演示組件

創建文件:app/screens/DemoShowroomScreen/demos/DemoHeartRateChart.tsx

import { HeartRateChart } from "../../../components"
import { View, StyleSheet } from "react-native"
import { Text } from "../../../components"export const DemoHeartRateChart = () => {return (<View style={styles.container}><Text preset="heading" style={styles.title}>24小時心率圖表</Text><HeartRateChart /></View>)
}const styles = StyleSheet.create({container: {alignItems: "center",padding: 20,},title: {marginBottom: 20,textAlign: "center",},
})

6.2 添加到演示頁面

app/screens/DemoShowroomScreen/DemoShowroomScreen.tsx 中:

import { FC } from "react"
import { Screen } from "../../components"
import { DemoHeartRateChart } from "./demos"export const DemoShowroomScreen: FC = function DemoShowroomScreen() {return (<Screen preset="fixed" safeAreaEdges={["top"]}><DemoHeartRateChart /></Screen>)
}

6.3 導出演示組件

app/screens/DemoShowroomScreen/demos/index.ts 中:

export * from "./DemoHeartRateChart"

7. 國際化支持

7.1 中文翻譯

app/i18n/zh.ts 中添加:

const zh = {// ... 其他翻譯demoShowroomScreen: {// ... 其他翻譯demoHeartRateChart: "心率圖表",demoHeartRateChartDesc: "一個顯示心率隨時間變化的圖表。",},
}

7.2 英文翻譯

app/i18n/en.ts 中添加:

const en = {// ... 其他翻譯demoShowroomScreen: {// ... 其他翻譯demoHeartRateChart: "Heart Rate Chart",demoHeartRateChartDesc: "A chart showing heart rate over time.",},
}

8. 最佳實踐

8.1 性能優化

  1. 使用useMemo緩存圖表配置
const chartOption = useMemo(() => {// 圖表配置邏輯
}, [data, theme])
  1. 合理管理圖表實例
useEffect(() => {let chartInstance: ECharts | undefinedif (chartRef.current && data.length > 0) {chartInstance = echarts.init(chartRef.current, "light", {renderer: "svg",width: CHART_WIDTH,height: CHART_HEIGHT,})chartInstance.setOption(chartOption)}return () => {chartInstance?.dispose()}
}, [chartOption])
  1. 避免不必要的重新渲染
const MemoizedChart = React.memo(HeartRateChart)

8.2 錯誤處理

  1. 數據驗證
const chartOption = useMemo(() => {if (!data || data.length === 0) {return {}}// 圖表配置
}, [data])
  1. 權限檢查
useEffect(() => {if (permissionsGranted) {fetchData()}
}, [permissionsGranted])
  1. 加載狀態
{isLoading && <LoadingSpinner />}
{error && <ErrorMessage error={error} onRetry={fetchData} />}

8.3 響應式設計

  1. 動態尺寸
const [chartSize, setChartSize] = useState({ width: 350, height: 300 })useEffect(() => {const updateSize = () => {const { width } = Dimensions.get('window')setChartSize({width: width - 40, // 減去paddingheight: 300,})}updateSize()Dimensions.addEventListener('change', updateSize)return () => {Dimensions.removeEventListener('change', updateSize)}
}, [])
  1. 主題適配
const chartOption = useMemo(() => ({// ... 其他配置backgroundColor: theme.colors.background,textStyle: {color: theme.colors.text,},
}), [theme, data])

8.4 統一ECharts實例管理

為了避免在多個組件中重復初始化ECharts模塊導致 [ReferenceError: Property 'document' doesn't exist] 等問題,建議創建一個中心化的echarts.ts文件來統一管理ECharts實例和模塊注冊。

創建 app/utils/echarts.ts:

import * as echarts from "echarts/core"
import { SVGRenderer } from "@wuba/react-native-echarts/svgChart"
import {LineChart,BarChart,GaugeChart,CustomChart,
} from "echarts/charts"
import {GridComponent,TooltipComponent,LegendComponent,
} from "echarts/components"// 注冊所有需要的組件
echarts.use([SVGRenderer,LineChart,BarChart,GaugeChart,CustomChart,GridComponent,TooltipComponent,LegendComponent,
])export { echarts }

在組件中使用:

import { echarts } from "../utils/echarts" // 導入集中的 echarts 實例
// ...
// 不再需要 echarts.use(...)

9. 常見問題

9.1 圖表不顯示

問題:圖表組件渲染但圖表內容不顯示

解決方案

  1. 檢查模塊注冊:確保所有需要的圖表類型(如 LineChart)和組件(如 TooltipComponent)都已在 app/utils/echarts.ts 中導入并使用 echarts.use() 注冊。這是最常見的原因,尤其是在添加新圖表類型后。
  2. 確認容器尺寸:確保 <SvgChart> 組件或其父容器具有明確的 widthheight 樣式。沒有尺寸,圖表將無法渲染。
  3. 驗證數據格式:檢查傳遞給 setOption 的配置對象中的 series.data 格式是否符合 ECharts 的要求。
  4. 查看初始化錯誤:在 useEffectecharts.init 的部分添加 try...catch 來捕獲任何初始化時拋出的錯誤。

示例:

// 1. 檢查 app/utils/echarts.ts
echarts.use([SVGRenderer,LineChart, // 確保已添加GridComponent,TooltipComponent,
])// 2. 在組件中設置明確的容器尺寸
<SvgChart ref={chartRef} style={{ width: 350, height: 300 }} />

9.2 數據更新不生效

問題:數據更新后圖表沒有重新渲染

解決方案

  1. 檢查useMemo的依賴數組
  2. 確保數據引用發生變化
  3. 驗證圖表實例是否正確更新
const chartOption = useMemo(() => {// 圖表配置
}, [data, theme]) // 確保包含所有依賴useEffect(() => {if (chartInstance && chartOption) {chartInstance.setOption(chartOption, true) // 第二個參數為true表示完全替換}
}, [chartOption])

9.3 性能問題

問題:圖表渲染導致性能問題

解決方案

  1. 使用數據采樣減少數據點
  2. 實現虛擬滾動
  3. 使用Web Worker處理大量數據
// 數據采樣
const sampledData = data.length > 1000 ? data.filter((_, index) => index % 10 === 0): data

9.4 內存泄漏

問題:組件卸載后圖表實例未正確清理

解決方案

  1. 在useEffect的清理函數中銷毀圖表實例
  2. 使用useRef確保引用一致性
useEffect(() => {let chartInstance: ECharts | undefinedif (chartRef.current) {chartInstance = echarts.init(chartRef.current)chartInstance.setOption(chartOption)}return () => {if (chartInstance) {chartInstance.dispose()}}
}, [chartOption])

總結

通過以上步驟,您可以在React Native項目中成功接入ECharts圖表。關鍵要點包括:

  1. 正確的依賴安裝和配置
  2. 合理的數據獲取和管理
  3. 優化的圖表配置和渲染
  4. 完善的錯誤處理和用戶體驗
  5. 性能優化和內存管理

這個解決方案提供了一個完整的圖表集成框架,可以根據具體需求進行擴展和定制。

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

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

相關文章

基于C#的OPCServer應用開發,引用WtOPCSvr.dll

操作流程&#xff1a; 1.引入WtOPCSvr.dll文件 2.注冊服務&#xff1a;使用UpdateRegistry方法注冊&#xff0c;注意關閉應用時使用UnregisterServer取消注冊。 3.初始化服務&#xff1a;使用InitWTOPCsvr初始化 4.使用CreateTag方法&#xff0c;創建標簽 5.讀寫參數使用下面三…

Java類加載器getResource行為簡單分析

今天嘗試集成一個第三方SDK&#xff0c;在IDE里運行正常&#xff0c;放到服務器上卻遇到了NPE&#xff0c;反編譯一看&#xff0c;原來在這一行&#xff1a;String path Test.class.getClassLoader().getResource("").getPath(); // Test.class.getClassLoader().ge…

【CodeTop】每日練習 2025.7.4

Leetcode 1143. 最長公共子序列 動態規劃解決&#xff0c;比較當前位置目標和實際字符串的字母&#xff0c;再根據不同情況計算接下來的情形。 class Solution {public int longestCommonSubsequence(String text1, String text2) {char[] t1 text1.toCharArray();char[] t2…

ES6從入門到精通:Promise與異步

Promise 基礎概念Promise 是 JavaScript 中處理異步操作的一種對象&#xff0c;代表一個異步操作的最終完成或失敗及其結果值。它有三種狀態&#xff1a;Pending&#xff08;進行中&#xff09;、Fulfilled&#xff08;已成功&#xff09;、Rejected&#xff08;已失敗&#xf…

數據結構:二維數組(2D Arrays)

目錄 什么是二維數組&#xff1f; 二維數組的聲明方式 方式 1&#xff1a;靜態二維數組 方式 2&#xff1a;數組指針數組&#xff08;數組中存放的是指針&#xff09; 方式 3&#xff1a;雙指針 二級堆分配 &#x1f4a1; 補充建議 如何用“第一性原理”去推導出 C 中…

HAProxy 和 Nginx的區別

HAProxy 和 Nginx 都是優秀的負載均衡工具&#xff0c;但它們在設計目標、適用場景和功能特性上有顯著區別。以下是兩者的詳細對比&#xff1a;1. 核心定位特性HAProxyNginx主要角色專業的負載均衡器/代理Web 服務器 反向代理/負載均衡設計初衷高性能流量分發高并發 HTTP 服務…

基于Java+SpringBoot的健身房管理系統

源碼編號&#xff1a;S586源碼名稱&#xff1a;基于SpringBoot的健身房管理系統用戶類型&#xff1a;多角色&#xff0c;用戶、教練、管理員數據庫表數量&#xff1a;13 張表主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven運行環境&#xff1a;Windows/Mac、JD…

【MySQL安裝-yum/手動安裝,卸載,問題排查處理完整文檔(linux)】

一.使用Yum倉庫自動安裝 步驟1:添加MySQL Yum倉庫 sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-6.noarch.rpm步驟2:安裝MySQL服務器 sudo yum install mysql-server -y步驟3:啟動并設置開機自啟 sudo systemctl start mysqld sudo systemct…

自定義線程池-實現任務0丟失的處理策略

設計一個線程池&#xff0c;要求如下&#xff1a;隊列最大容量為10&#xff08;內存隊列&#xff09;。當隊列滿了之后&#xff0c;拒絕策略將新的任務寫入數據庫。從隊列中取任務時&#xff0c;若該隊列為空&#xff0c;能夠從數據庫中加載之前被拒絕的任務模擬數據庫 (TaskDa…

【NLP入門系列四】評論文本分類入門案例

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 博主簡介&#xff1a;努力學習的22級本科生一枚 &#x1f31f;?&#xff1b;探索AI算法&#xff0c;C&#xff0c;go語言的世界&#xff1b;在迷茫中尋找光芒…

Ubuntu安裝ClickHouse

注&#xff1a;本文章的ubuntu的版本為&#xff1a;ubuntu-20.04.6-live-server-amd64。 Ubuntu&#xff08;在線版&#xff09; 更新軟件源 sudo apt-get update 安裝apt-transport-https 允許apt工具通過https協議下載軟件包。 sudo apt-get install apt-transport-htt…

C++26 下一代C++標準

C++26 將是繼 C++23 之后的下一個 C++ 標準。這個新標準對 C++ 進行了重大改進,很可能像 C++98、C++11 或 C++20 那樣具有劃時代的意義。 一:C++標準回顧 C++ 已經有 40 多年的歷史了。過去這些年里發生了什么?這里給出一個簡化版的答案,直到即將到來的 C++26。 1. C++9…

【MySQL】十六,MySQL窗口函數

在 MySQL 8.0 及以后版本中&#xff0c;窗口函數&#xff08;Window Functions&#xff09;為數據分析和處理提供了強大的工具。窗口函數允許在查詢結果集上執行計算&#xff0c;而不必使用子查詢或連接&#xff0c;這使得某些類型的計算更加高效和簡潔。 語法結構 function_…

微型氣象儀在城市環境的應用

微型氣象儀憑借其體積小、成本低、部署靈活、數據實時性強等特點&#xff0c;在城市環境中得到廣泛應用&#xff0c;能夠為城市規劃、環境管理、公共安全、居民生活等領域提供精細化氣象數據支持。一、核心應用場景1. 城市微氣候監測與優化熱島效應研究場景&#xff1a;在城市不…

【仿muduo庫實現并發服務器】eventloop模塊

仿muduo庫實現并發服務器一.eventloop模塊1.成員變量std::thread::id _thread_id;//線程IDPoller _poll;int _event_fd;std::vector<Function<Function>> _task;TimerWheel _timer_wheel2.EventLoop構造3.針對eventfd的操作4.針對poller的操作5.針對threadID的操作…

Redis 加鎖、解鎖

Redis 加鎖和解鎖的應用 上代碼 應用調用示例 RedisLockEntity lockEntityYlb RedisLockEntity.builder().lockKey(TradeConstants.HP_APP_AMOUNT_LOCK_PREFIX appUser.getAccount()).value(orderId).build();boolean isLockedYlb false;try {if (redisLock.tryLock(lockE…

在 Windows 上為 WSL 增加 root 賬號密碼并通過 Shell 工具連接

1. 為 WSL 設置 root 用戶密碼 在 Windows 上使用 WSL&#xff08;Windows Subsystem for Linux&#xff09;時&#xff0c;默認情況下并沒有啟用 root 賬號的密碼。為了通過 SSH 或其他工具以 root 身份連接到 WSL&#xff0c;我們需要為 root 用戶設置密碼。 設置 root 密碼步…

2730、找到最長的半重復子字符穿

題目&#xff1a; 解答&#xff1a; 窗口為[left&#xff0c;right]&#xff0c;ans為窗口長度&#xff0c;same為子串長度&#xff0c;窗口滿足題設條件&#xff0c;即只含一個連續重復字符&#xff0c;則更新ans&#xff0c;否則從左邊開始一直彈出&#xff0c;直到滿足條件…

MCP Java SDK源碼分析

MCP Java SDK源碼分析 一、引言 在當今人工智能飛速發展的時代&#xff0c;大型語言模型&#xff08;LLMs&#xff09;如GPT - 4、Claude等展現出了強大的語言理解和生成能力。然而&#xff0c;這些模型面臨著一個核心限制&#xff0c;即無法直接訪問外部世界的數據和工具。M…

[Linux]內核如何對信號進行捕捉

要理解Linux中內核如何對信號進行捕捉&#xff0c;我們需要很多前置知識的理解&#xff1a; 內核態和用戶態的區別CPU指令集權限內核態和用戶態之間的切換 由于文章的側重點不同&#xff0c;上面這些知識我會在這篇文章盡量詳細提及&#xff0c;更詳細內容還得請大家查看這篇…