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

axios和fetch的实现原理以及区别,与XMLHttpRequest的关系,并结合react封装统一请求示例

Axios 和 Fetch 对比及统一请求封装

1. Axios 基础用法

1.1 安装和引入

// 安装
npm install axios// 引入
import axios from 'axios';

1.2 基本请求方法

// GET 请求
axios.get('/api/users').then(response => console.log(response.data)).catch(error => console.error(error));// POST 请求
axios.post('/api/users', {name: 'John',age: 30
}).then(response => console.log(response.data)).catch(error => console.error(error));// PUT 请求
axios.put('/api/users/1', {name: 'John',age: 31
});// DELETE 请求
axios.delete('/api/users/1');// 使用 async/await
async function fetchData() {try {const response = await axios.get('/api/users');console.log(response.data);} catch (error) {console.error(error);}
}

1.3 配置选项

// 全局配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = 'Bearer token';
axios.defaults.timeout = 5000;// 请求配置
axios({method: 'post',url: '/api/users',data: {name: 'John',age: 30},headers: {'Content-Type': 'application/json'},timeout: 5000,withCredentials: true
});// 创建实例
const instance = axios.create({baseURL: 'https://api.example.com',timeout: 5000,headers: {'X-Custom-Header': 'value'}
});

2. Fetch 基础用法

2.1 基本请求方法

// GET 请求
fetch('/api/users').then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));// POST 请求
fetch('/api/users', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({name: 'John',age: 30})
}).then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));// 使用 async/await
async function fetchData() {try {const response = await fetch('/api/users');const data = await response.json();console.log(data);} catch (error) {console.error(error);}
}

2.2 请求配置

fetch('/api/users', {method: 'POST',headers: {'Content-Type': 'application/json','Authorization': 'Bearer token'},body: JSON.stringify(data),mode: 'cors',credentials: 'include',cache: 'no-cache',redirect: 'follow'
});

3. Axios 和 Fetch 的主要区别

3.1 功能差异

  1. 请求/响应拦截
// Axios 支持拦截器
axios.interceptors.request.use(config => {// 请求前处理return config;
}, error => {return Promise.reject(error);
});axios.interceptors.response.use(response => {// 响应后处理return response;
}, error => {return Promise.reject(error);
});// Fetch 需要自行封装
const fetchWithInterceptor = async (...args) => {// 请求前处理const response = await fetch(...args);// 响应后处理return response;
};
  1. 自动转换 JSON
// Axios 自动转换 JSON
axios.get('/api/users').then(response => console.log(response.data)); // 直接获取数据// Fetch 需要手动转换
fetch('/api/users').then(response => response.json()).then(data => console.log(data));
  1. 错误处理
// Axios 统一处理错误
axios.get('/api/users').catch(error => {if (error.response) {// 服务器响应错误console.log(error.response.status);} else if (error.request) {// 请求未收到响应console.log(error.request);} else {// 请求配置错误console.log(error.message);}});// Fetch 需要手动检查状态
fetch('/api/users').then(response => {if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}return response.json();}).catch(error => console.log(error));

3.2 浏览器支持

  • Fetch: 现代浏览器原生支持,但不支持 IE
  • Axios: 支持所有主流浏览器,包括 IE11

4. React 统一请求封装

4.1 基于 Axios 的封装

// src/utils/request.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { message } from 'antd';// 请求配置类型
interface RequestConfig extends AxiosRequestConfig {loading?: boolean;skipErrorHandler?: boolean;
}// 响应数据类型
interface ResponseData<T = any> {code: number;data: T;message: string;
}class Request {private instance: AxiosInstance;private loading: boolean;constructor() {this.instance = axios.create({baseURL: process.env.REACT_APP_API_URL,timeout: 10000,headers: {'Content-Type': 'application/json'}});this.loading = false;this.setupInterceptors();}private setupInterceptors() {// 请求拦截器this.instance.interceptors.request.use((config: RequestConfig) => {// 添加 tokenconst token = localStorage.getItem('token');if (token) {config.headers.Authorization = `Bearer ${token}`;}// 显示加载状态if (config.loading) {this.loading = true;// 可以使用 antd 的 loading 组件}return config;},error => {return Promise.reject(error);});// 响应拦截器this.instance.interceptors.response.use((response: AxiosResponse<ResponseData>) => {// 隐藏加载状态this.loading = false;const { code, data, message: msg } = response.data;// 处理业务错误if (code !== 0) {if (!response.config.skipErrorHandler) {message.error(msg || '请求失败');}return Promise.reject(new Error(msg || '请求失败'));}return data;},error => {// 隐藏加载状态this.loading = false;// 处理 HTTP 错误if (!error.config?.skipErrorHandler) {if (error.response) {switch (error.response.status) {case 401:message.error('未授权,请重新登录');// 可以在这里处理登出逻辑break;case 403:message.error('拒绝访问');break;case 404:message.error('请求的资源不存在');break;case 500:message.error('服务器错误');break;default:message.error(`请求失败: ${error.message}`);}} else {message.error('网络错误,请检查网络连接');}}return Promise.reject(error);});}// 通用请求方法public async request<T = any>(config: RequestConfig): Promise<T> {try {const response = await this.instance.request<any, T>(config);return response;} catch (error) {return Promise.reject(error);}}// GET 请求public get<T = any>(url: string, config?: RequestConfig): Promise<T> {return this.request({ ...config, method: 'GET', url });}// POST 请求public post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {return this.request({ ...config, method: 'POST', url, data });}// PUT 请求public put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T> {return this.request({ ...config, method: 'PUT', url, data });}// DELETE 请求public delete<T = any>(url: string, config?: RequestConfig): Promise<T> {return this.request({ ...config, method: 'DELETE', url });}
}export default new Request();

4.2 使用示例

// src/api/user.ts
import request from '@/utils/request';interface User {id: number;name: string;age: number;
}export const userApi = {// 获取用户列表getUsers: () => request.get<User[]>('/api/users'),// 获取用户详情getUser: (id: number) => request.get<User>(`/api/users/${id}`),// 创建用户createUser: (data: Omit<User, 'id'>) => request.post<User>('/api/users', data),// 更新用户updateUser: (id: number, data: Partial<User>) =>request.put<User>(`/api/users/${id}`, data),// 删除用户deleteUser: (id: number) =>request.delete(`/api/users/${id}`)
};// 在组件中使用
import React, { useEffect, useState } from 'react';
import { userApi } from '@/api/user';const UserList: React.FC = () => {const [users, setUsers] = useState<User[]>([]);useEffect(() => {const fetchUsers = async () => {try {const data = await userApi.getUsers();setUsers(data);} catch (error) {console.error('Failed to fetch users:', error);}};fetchUsers();}, []);const handleCreateUser = async () => {try {const newUser = await userApi.createUser({name: 'John',age: 30});setUsers(prev => [...prev, newUser]);} catch (error) {console.error('Failed to create user:', error);}};return (<div>{/* 渲染用户列表 */}</div>);
};export default UserList;

5. 最佳实践建议

1. 选择建议

  • 小型项目:使用 Fetch 足够
  • 大型项目:推荐使用 Axios(功能更完善)
  • 需要兼容 IE:必须使用 Axios

2. 性能优化

  • 合理使用请求取消
  • 实现请求缓存
  • 避免重复请求

3. 安全考虑

  • 统一处理敏感信息
  • 实现请求超时
  • CSRF 防护

4. 开发建议

  • 使用 TypeScript 增加类型安全
  • 集中管理 API 请求
  • 做好错误处理
  • 添加请求日志

6. fetch实现原理

fetch 是一种用于在浏览器中发起 HTTP 请求并获取响应的 API,它是 XMLHttpRequest 的现代替代品。fetch 基于 Promise,使得异步代码更加简洁和易于理解。它的实现原理是利用浏览器提供的低级 API 来执行 HTTP 请求和处理响应。

1. fetch 的基本使用

fetch 接口允许你通过网络发起请求并返回响应,它的基本语法如下:

fetch(url, options).then(response => response.json())  // 或者 response.text(), response.blob() 等.then(data => console.log(data)).catch(error => console.log(error));

url:要请求的资源地址。
options(可选):一个包含配置选项的对象,用于配置请求方法、请求头、请求体等。

2. fetch 的底层实现原理

fetch 是基于浏览器的 Fetch API 实现的,它的实现原理依赖于以下几个关键步骤:

2.1 发起 HTTP 请求

当你调用 fetch 时,浏览器通过 HTTP 协议 向目标 URL 发送请求。这个请求可以是 GET、POST、PUT 等类型,并且可以包含请求头和请求体(例如,POST 请求通常包含数据)。

在底层,fetch 会使用 浏览器的网络栈(例如,TCP/IP 协议、TLS/SSL 等)通过 DNS 查询目标服务器的 IP 地址,建立网络连接,并发送 HTTP 请求。

2.2 异步请求与 Promise

fetch 是基于 Promise 的,它允许我们在请求完成后异步处理结果。这意味着当你调用 fetch 时,浏览器会立即发起请求并返回一个未完成的 Promise。then 方法中传入的回调函数会在请求完成时被调用,而 catch 会捕获任何可能发生的错误。

例如:

fetch(url)   // 发起请求并返回一个 Promise.then(response => {console.log("Response received");return response.json();   // 解析 JSON 数据}).catch(error => console.log(error));  // 捕获错误

在浏览器中,fetch 实际上是通过 JavaScript 事件循环机制调度 HTTP 请求,它不会阻塞主线程。由于 fetch 是异步的,它允许页面在等待请求返回的同时执行其他任务。

2.3 请求头与配置

在 fetch 请求中,你可以通过 options 对象来配置请求。例如,你可以设置请求方法(GET、POST 等),设置请求头,发送请求体等。

const options = {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ key: 'value' })  // 请求体
};fetch(url, options).then(response => response.json()).then(data => console.log(data)).catch(error => console.log(error));

这些选项会通过浏览器的 HTTP 客户端 发送到服务器。浏览器会根据请求的类型和配置,构建相应的 HTTP 请求头部和请求体。

2.4 响应处理

fetch 发起请求并接收响应时,它返回的 response 对象代表 HTTP 响应。这些响应信息包括状态码、响应头和响应体内容。

fetch(url).then(response => {if (!response.ok) {throw new Error('Network response was not ok');}return response.json();   // 返回 JSON 数据}).then(data => console.log(data)).catch(error => console.log(error));

response.ok 是一个布尔值,表示响应是否成功(状态码 200 到 299 表示成功)。response.json()、response.text()、response.blob() 等方法允许你读取响应体内容。

2.5 CORS(跨域资源共享)

当你发起跨域请求时,浏览器会处理跨域资源共享(CORS)问题。fetch 会自动处理 预检请求(OPTIONS 请求),并根据目标服务器的 CORS 策略决定是否允许访问。

如果服务器响应了正确的 CORS 头部,浏览器会允许访问并返回资源。
如果服务器未响应适当的 CORS 头部,fetch 请求将被阻止,并抛出一个错误。

3. 底层实现

从实现角度来看,fetch 依赖于浏览器内部的网络通信堆栈。以下是 fetch 实现的几个关键点:

请求建立:

当 fetch 被调用时,浏览器会通过其网络库(如 libcurl 或原生的浏览器网络栈)解析 URL、进行 DNS 查询、建立 TCP 连接。
发送请求:

浏览器根据配置(如请求方法、头部、体等)构造 HTTP 请求并发送到目标服务器。
等待响应:

请求发送后,浏览器会等待响应。浏览器根据响应的 HTTP 状态码和头部信息来判断请求是否成功。
解析响应:

浏览器收到响应后,会将响应内容存储在 response 对象中,并提供如 response.json()、response.text() 等方法来解析响应内容。
事件循环和 Promise:

fetch 的操作是异步的,基于 事件循环 机制和 Promise。当响应可用时,相关的 .then() 或 .catch() 方法会被执行。

4. 与 XMLHttpRequest 的对比

fetch 与传统的 XMLHttpRequest (XHR) 相比,有以下几个主要优势:

Promise 支持:fetch 基于 Promise,使得代码更加简洁和易于理解,避免了回调地狱。

简洁的 API:fetch 的 API 更加简洁,尤其是在处理响应体时。你只需要使用 .json()、.text()、.blob() 等方法来解析响应内容,而 XMLHttpRequest 需要更多的手动配置。

默认不发送 Cookies:fetch 默认不会发送跨域请求时的 Cookies(除非配置了 credentials 选项)。而 XMLHttpRequest 默认会自动发送 Cookies。

支持流式传输:fetch 支持响应流(ReadableStream),允许更高效地处理大文件和流式响应。

5. 总结

fetch 是现代浏览器中用来发起 HTTP 请求的原生 API,它依赖浏览器的网络堆栈来执行低级别的请求操作。通过基于 Promise 的设计,fetch 提供了更清晰的异步操作流程。它的实现利用了浏览器的网络层和异步编程机制,能够有效处理 HTTP 请求、响应、CORS 等问题。

7. fetch和XMLHttpRequest区别

fetch 和 XMLHttpRequest 都是浏览器提供的用于发起 HTTP 请求的 API,尽管它们的目的相同——发送和接收数据——它们在设计、功能、使用方式和底层实现上有许多差异。下面是它们之间的关系和主要区别:

1. 关系:

功能相似:fetch 和 XMLHttpRequest 都用于从客户端(浏览器)发送 HTTP 请求到服务器,并获取响应。这意味着它们都可以用来发送数据(如表单提交、获取 API 数据等)。
底层原理:虽然 fetch 是现代浏览器的标准 API,而 XMLHttpRequest 是较旧的标准 API,但它们都通过浏览器的网络堆栈与服务器通信。fetch 是 XMLHttpRequest 的替代品,提供了更现代、更简洁的 API。
异步操作:fetch 和 XMLHttpRequest 都是异步的,可以执行异步 HTTP 请求,但 fetch 使用了更现代的 Promise 机制,而 XMLHttpRequest 主要基于回调(callback)机制。

2. 主要区别:

2.1 API 风格和易用性

fetch:

基于 Promise,支持链式调用,使代码更加简洁和易于维护。
语法简洁,只返回响应的 response 对象,不会自动处理请求错误(需要手动检查状态码和抛出错误)。
采用更现代的设计,支持 async/await,使得处理异步操作更自然。
示例:

fetch(url).then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));

XMLHttpRequest:

基于回调机制,使用 onreadystatechange 或 onload 事件处理响应,导致代码更复杂,容易出现回调地狱(callback hell)。
没有内置的 Promise 支持,因此通常与回调函数或外部库(如 jQuery)一起使用来简化操作。
示例:

const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {const data = JSON.parse(xhr.responseText);console.log(data);}
};
xhr.send();
2.2 请求和响应的处理

fetch:
返回的是一个 Promise,这意味着响应是异步处理的,并且通过 then() 或 async/await 进行响应数据的处理。
不会自动抛出 HTTP 错误(如 404 或 500),需要手动检查 response.ok 或 response.status 来判断请求是否成功。
XMLHttpRequest:
使用事件回调处理响应,通常是通过 onload 或 onreadystatechange 来处理请求的响应。
自动将响应文本(responseText)作为字符串返回,解析 JSON 或其他数据类型需要手动处理。
XMLHttpRequest 会自动在请求失败时调用 onerror 回调函数。

2.3 错误处理

fetch:

默认不会对 HTTP 错误(如 404、500)抛出错误,只有网络错误(例如无网络连接)才会触发 .catch()。
需要手动检查 response.ok 或 response.status 来判断响应是否成功。
示例:

fetch(url).then(response => {if (!response.ok) {throw new Error('Network response was not ok');}return response.json();}).then(data => console.log(data)).catch(error => console.error('Fetch error:', error));

XMLHttpRequest:

XMLHttpRequest 会根据请求的状态码来执行相应的回调方法,通常是通过检查 xhr.status 来判断请求是否成功。

2.4 请求体处理

fetch:

直接支持通过 body 选项发送请求体(如发送 JSON 数据),且支持 FormData、Blob、ArrayBuffer 等多种数据类型。
通过 headers 选项配置请求头。
示例:

const options = {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ key: 'value' })
};fetch(url, options).then(response => response.json()).then(data => console.log(data));

XMLHttpRequest:

需要手动设置请求头,并使用 xhr.send() 发送请求体。
对发送 JSON 数据通常需要手动字符串化,并设置 Content-Type 头部。
示例:

const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ key: 'value' }));
2.5 跨域请求(CORS)

fetch:

默认支持跨域请求(CORS),但需要服务器在响应中包含适当的 CORS 头部。
可以通过 credentials 选项来控制是否发送 Cookies、授权头等。
示例:

fetch(url, { credentials: 'same-origin' }).then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));

XMLHttpRequest:

支持跨域请求,但需要手动处理 CORS(通常在跨域时需要服务器添加 CORS 头部)。
默认发送跨域请求时不会携带 Cookies。

2.6 流式响应(Streams)

fetch:

支持流式响应,允许逐步处理大文件或大数据集。响应体是一个 ReadableStream,这使得你可以逐步读取数据而不是一次性获取整个响应。
示例:

fetch(url).then(response => {const reader = response.body.getReader();reader.read().then(function processText({ done, value }) {if (done) return;console.log(value);reader.read().then(processText);});});

XMLHttpRequest:

不支持流式响应。它需要等待整个响应下载完毕才会调用回调函数。

2.7 支持情况

fetch:

fetch 是一个现代的 API,已被大多数现代浏览器(如 Chrome、Firefox、Edge、Safari)支持,但在一些旧版本的浏览器中(如 Internet Explorer)不支持。
需要通过 polyfill 来在不支持的浏览器中使用。
XMLHttpRequest:

XMLHttpRequest 在所有主流浏览器中都被广泛支持,包括旧版本的浏览器(如 Internet Explorer)。

3. 总结

fetch 是一个现代的、基于 Promise 的 API,具有更简洁的语法和更强大的功能,如流式响应、异步操作的简化、更易于使用的错误处理等。
XMLHttpRequest 是较老的 API,基于回调机制,功能上不如 fetch 灵活和简洁,但仍然被广泛使用,特别是在一些较旧的浏览器中。
尽管 fetch 是 XMLHttpRequest 的现代替代品,XMLHttpRequest 仍然存在于许多遗留的代码中。fetch 是未来的主流选择,而 XMLHttpRequest 在许多场景下也依然可用,尤其是与旧版本的浏览器兼容时。

8. Axios的实现原理

Axios 是一个基于 Promise 的 JavaScript 库,用于简化浏览器和 Node.js 环境中的 HTTP 请求。Axios 主要通过封装 XMLHttpRequest 或 Node.js 的 http/https 模块 来实现对 HTTP 请求的支持,而 并没有直接封装 fetch。

1. 浏览器中的实现

在 浏览器环境 中,Axios 默认使用 XMLHttpRequest 进行 HTTP 请求。XMLHttpRequest 是浏览器中较早的一个用于发起 HTTP 请求的 API,广泛支持,并且可以处理浏览器中常见的 HTTP 请求需求。

使用 XMLHttpRequest:
在浏览器环境中,Axios 封装了 XMLHttpRequest,对其进行了改造和增强,使得 API 使用更加简洁。
通过封装,Axios 提供了基于 Promise 的异步编程模型,支持链式调用、请求和响应拦截、请求取消、自动转换 JSON 数据等功能。
Axios 还会自动处理一些常见的错误情况(如 404、500 错误)并通过 Promise 抛出异常,方便开发者统一处理。
示例:Axios 在浏览器中的基本实现(简化版)

// 伪代码,简化版
function axiosRequest(config) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();xhr.open(config.method, config.url, true);// 设置请求头Object.keys(config.headers).forEach(key => {xhr.setRequestHeader(key, config.headers[key]);});xhr.onload = function () {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response);  // 请求成功,解析响应} else {reject(new Error('Request failed with status code ' + xhr.status));  // 请求失败}};xhr.onerror = function () {reject(new Error('Network Error'));  // 网络错误};// 发送请求xhr.send(config.data);});
}

2. Node.js 中的实现

在 Node.js 环境 中,Axios 不是使用 XMLHttpRequest,因为 XMLHttpRequest 是浏览器专有的 API,而是使用 Node.js 原生的 http 和 https 模块 来发起 HTTP 请求。

使用 http/https 模块:
在 Node.js 中,Axios 使用 Node.js 自带的 HTTP 库 (http 或 https),这些库非常适合用于服务器端请求。
Axios 将 HTTP 请求和响应处理的过程封装为 Promise,允许开发者通过链式调用来处理异步操作。
示例:Axios 在 Node.js 中的基本实现(简化版)

// 伪代码,简化版
const http = require('http');
const https = require('https');function axiosRequest(config) {return new Promise((resolve, reject) => {const client = config.url.startsWith('https') ? https : http;const req = client.request(config.url, { method: config.method, headers: config.headers }, (res) => {let data = '';// 接收数据res.on('data', chunk => {data += chunk;});res.on('end', () => {if (res.statusCode >= 200 && res.statusCode < 300) {resolve(data);  // 请求成功,解析响应} else {reject(new Error('Request failed with status code ' + res.statusCode));  // 请求失败}});});req.on('error', (e) => {reject(e);  // 网络错误});// 发送请求req.write(config.data);req.end();});
}

3. Axios 与 fetch 的关系

Axios 和 fetch 都是基于 Promise 的异步 API,功能上有很多相似之处,例如:

都支持发起 GET、POST 等 HTTP 请求。
都支持 Promise,允许链式调用。
都允许设置请求头、请求体、超时等配置。
然而,Axios 并没有直接基于 fetch 封装。虽然 fetch 是现代浏览器中用于发起 HTTP 请求的推荐 API,Axios 仍然选择使用 XMLHttpRequest 在浏览器中发起请求,原因如下:

更广泛的兼容性:XMLHttpRequest 在较旧的浏览器中也有很好的支持,尤其是在像 Internet Explorer 这样的旧版浏览器中。fetch 相对较新,部分旧浏览器不支持,需要 polyfill 来补充支持。

功能扩展:Axios 提供了一些 fetch 不直接支持的功能,比如请求拦截器、响应拦截器、自动转换 JSON 数据、请求取消、默认超时处理等。

简化错误处理:fetch 本身不会自动抛出 HTTP 错误(如 404 或 500 错误),需要开发者手动检查 response.ok。而 Axios 会根据 HTTP 状态码自动抛出异常,简化了错误处理。

4. 总结

Axios 的实现原理:Axios 在 浏览器中使用 XMLHttpRequest,在 Node.js 中使用 http 或 https 模块 来发起 HTTP 请求。
Axios 并没有封装 fetch,尽管它与 fetch 有一些相似之处。Axios 提供了更多的功能(如请求拦截、响应拦截、自动 JSON 转换等),并选择了在浏览器中使用 XMLHttpRequest 来确保更广泛的兼容性。

相关文章:

axios和fetch的实现原理以及区别,与XMLHttpRequest的关系,并结合react封装统一请求示例

Axios 和 Fetch 对比及统一请求封装 1. Axios 基础用法 1.1 安装和引入 // 安装 npm install axios// 引入 import axios from axios;1.2 基本请求方法 // GET 请求 axios.get(/api/users).then(response > console.log(response.data)).catch(error > console.error…...

矩阵运算提速——玩转opencv::Mat

介绍:用Eigen或opencv::Mat进行矩阵的运算&#xff0c;比用cpp的vector或vector进行矩阵运算要快吗? 使用 Eigen 或 OpenCV 的 cv::Mat 进行矩阵运算通常比使用 std::vector<int> 或 std::vector<double> 更快。这主要有以下几个原因&#xff1a; 优化的底层实现…...

C++软件设计模式之模板方法模式

模板方法模式是面向对象软件设计模式之一&#xff0c;其主要意图是在一个方法中定义一个算法的骨架&#xff0c;而将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。 动机 在软件开发中&#xff0c;常常会遇到这样的情…...

神经网络的初始化方式都有哪些?

一、概念 神经网络的初始化是深度学习中的一个关键步骤&#xff0c;它指的是在训练开始前为神经网络的权重和偏置设置初始值。合适的初始化方法可以加速模型的收敛&#xff0c;提高训练效果&#xff0c;甚至影响模型的最终性能。当然&#xff0c;目前我们使用Torch、TensorFlow…...

const成员函数

在c中经常看到这样的声明&#xff1a; class A{ ... int fun1() const; //const成员函数 int fun2() const; //const成员函数private: int a; //属于状态 static int b; //不属于状态&#xff0c;属于类 } 这个const关键字声明了这个函数是const成员函数&#xff0c;con…...

物理知识1——电流

说起电流&#xff0c;应该从电荷说起&#xff0c;而说起电荷&#xff0c;应该从原子说起。 1 原子及其结构 常见的物质是由分子构成的&#xff0c;而分子又是由原子构成的&#xff0c;有的分子是由多个原子构成&#xff0c;有的分子只由一个原子构成。而原子的构成如图1所示。…...

车载通信架构 --- 智能汽车通信前沿技术

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...

Flutter中添加全局防护水印的实现

随着版权意识的加强&#xff0c;越来越多的应用开始在应用内部增加各种各样的水印信息&#xff0c;防止核心信息泄露&#xff0c;便于朔源。 效果如下&#xff1a; 在Flutter中增加全局水印的方式&#xff0c;目前有两种实现。 方案一&#xff0c;在native层添加一个遮罩层&a…...

BGP(Border Gateway Protocol)路由收集器

全球 BGP&#xff08;边界网关协议&#xff09;路由收集器的分布情况以及相关数据。以下是主要的信息解读&#xff1a; 地图标记&#xff1a; 每个绿色点代表一个路由收集器的位置。路由收集器分布在全球不同的地区&#xff0c;覆盖了五大区域&#xff1a; ARIN&#xff08;美…...

【DAGMM】直接跑tip

1.from sklearn.externals import joblib 版本高 joblib没有 直接pip install joblib&#xff0c;然后 import joblib 2.AttributeError: module ‘tensorflow’ has no attribute ‘set_random_seed’ # tf.set_random_seed(args.seed)#tf<2.0 tf.random.set_seed(args.s…...

vscode中调用deepseek实现AI辅助编程

来自 Python大数据分析 费弗里 1 简介 大家好我是费老师&#xff0c;最近国产大模型Deepseek v3新版本凭借其优秀的模型推理能力&#xff0c;讨论度非常之高&#x1f525;&#xff0c;且其官网提供的相关大模型API接口服务价格一直走的“价格屠夫”路线&#xff0c;性价比很高…...

AI大模型语音识别转文字

提取音频 本项目作用在于将常见的会议录音文件、各种语种音频文件进行转录成相应的文字&#xff0c;也可从特定视频中提取对应音频进行转录成文字保存在本地。最原始的从所给网址下载对应视频和音频进行处理。下载ffmpeg(https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-…...

可由 (5V) 单片机直接驱动的模块

可由 &#xff08;5V&#xff09; 单片机 直接驱动的模块 1. 传感器类 元器件描述温度传感器DS18B20&#xff08;数字温度传感器&#xff09;光强传感器光敏电阻&#xff08;通过 ADC 读取&#xff09;红外传感器红外接收模块&#xff08;如 VS1838&#xff09;超声波传感器HC…...

vue使用树形结构展示文件和文件夹

1. 树形结构显示 显示文件夹和文件&#xff1a;使用 el-tree 组件展示树形结构&#xff0c;文件夹和文件的图标通过 el-icon 进行动态显示。文件夹使用 Folder 图标&#xff0c;文件使用 Files 图标。节点点击&#xff1a;点击树形节点后&#xff0c;会将选中的节点保存到 sel…...

PHP框架+gatewayworker实现在线1对1聊天--聊天界面布局+创建websocket连接(5)

文章目录 聊天界面布局html代码 创建websocket连接为什么要绑定&#xff1f; 聊天界面布局 在View/Index目录下创建index.html html代码 <div id"chat"><div id"nbar"><div class"pull-left">与牛德胜正在聊天...</div…...

LinuxUbuntu打开VSCode白屏解决方案

解决方法是 以root权限打开VSCode sudo /usr/share/code/code --no-sandbox --unity-launch...

在 ESP 上运行 AWTK

AWTK 基于 esp 的移植。 测试硬件平台为 ESP32-S3-Touch-LCD-4.3&#xff0c;其它平台请根据实际平台自行调整。 安装下载工具 建议下载离线版本 ESP IDF v5.3.2 下载代码 git clone https://github.com/zlgopen/awtk-esp.git cd awtk-esp git clone https://github.com/zlg…...

硬件工程师面试题 21-30

把常见的硬件面试题进行总结&#xff0c;方便及时巩固复习。其中包括网络上的资源、大佬们的大厂面试题&#xff0c;其中可能会题目类似&#xff0c;加强印象即可。 更多硬件面试题&#xff1a;硬件工程师面试题 1-10硬件工程师面试题 11-20 21、单片机最小系统需要什么&#x…...

开源架构的容器化部署优化版

上三篇文章推荐&#xff1a; 开源架构的微服务架构实践优化版&#xff08;New&#xff09; 开源架构中的数据库选择优化版&#xff08;New&#xff09; 开源架构学习指南&#xff1a;文档与资源的智慧锦囊&#xff08;New&#xff09; 我管理的社区推荐&#xff1a;【青云交社区…...

Qt使用CMake编译项目时报错:#undefined reference to `vtable for MainView‘

博主将.h文件和.cpp文件放到了不同的文件目录下面&#xff0c;如下图所示&#xff1a; 于是构建项目的时候就报错了#undefined reference to vtable for MainView&#xff0c;这个是由于src/view目录下的CMake无法自动moc头文件导致的&#xff0c;需要手动moc include/view目录…...

python学习笔记—12—

1. 布尔类型 (1) 定义 (2) 比较运算符 (3) 代码演示 1. 手动定义 bool_1 True bool_2 False print(f"bool_1的内容是&#xff1a;{bool_1}, 类型是&#xff1a;{type(bool_1)}") print(f"bool_2的内容是&#xff1a;{bool_2}, 类型是&#xff1a;{type(bool…...

==和===的区别,被坑的一天

在 JavaScript 中&#xff0c; 和 都用于比较两个值&#xff0c;但它们有一个重要的区别&#xff1a; 1. (宽松相等运算符) 进行比较时&#xff0c;会 自动类型转换&#xff08;也叫做强制类型转换&#xff09;&#xff0c;即如果比较的两个值的类型不同&#xff0c;JavaScr…...

基于 GPUTasker 的 GPU 使用情况钉钉推送机器人实现

引言 https://github.com/cnstark/gputasker 随着 AI 模型的广泛应用&#xff0c;GPU 成为团队中最重要的资源之一。然而&#xff0c;如何实时监控 GPU 的使用情况并及时通知团队是一个值得关注的问题。为了更好地管理显卡资源&#xff0c;本文基于 GPUTasker&#xff0c;实现了…...

Python自学 - 函数初步(内置函数、模块函数、自定义函数)

1 Python自学 - 函数初步(内置函数、模块函数、自定义函数) 1.1 内置函数 几乎所有的编程都会提供一些内置函数&#xff0c;以便完成一些最基本的任务&#xff0c;Python提供了丰富的内置函数&#xff0c;熟悉内置函数可以给工作带来极大便利。   Python官方的内置函数介绍网…...

【生活】冬天如何选口罩(医用口罩,N95, KN95还是KP95?带不带呼吸阀门?带不带活性炭?)

&#x1f4a1;总结一下就是&#xff1a; 日常防护的话&#xff0c;医用口罩就可以啦。要是想长时间佩戴N95&#xff08;KN95&#xff09;口罩的话也可以. 在高风险环境&#xff08;像医院、疫情防控期间&#xff09;&#xff0c;一定要选不带呼吸阀门的N95口罩KN95&#xff09…...

HTML5新特性|01 音频视频

音频 1、Audio (音频) HTML5提供了播放音频文件的标准 2、control(控制器) control 属性供添加播放、暂停和音量控件 3、标签: <audio> 定义声音 <source> 规定多媒体资源,可以是多个<!DOCTYPE html> <html lang"en"> <head><…...

迅为RK3568开发板编译Android12源码包-设置屏幕配置

在源码编译之前首先要确定自己想要使用的屏幕并修改源码&#xff0c;在编译镜像&#xff0c;烧写镜像。如下图所示&#xff1a; 第一步&#xff1a;确定要使用的屏幕种类&#xff0c;屏幕种类选择如下所示&#xff1a; iTOP-3568 开发板支持以下种类屏幕&#xff1a; 迅为 LV…...

力扣hot100——图论

200. 岛屿数量 class Solution { public:int numIslands(vector<vector<char>>& grid) {int ans 0;vector<int> dx { 0, 1, 0, -1 };vector<int> dy { 1, 0, -1, 0 };int n grid.size(), m grid[0].size();vector<vector<int>> …...

Docker- Unable to find image “hello-world“locally

Docker- Unable to find image “hello-world“locally 文章目录 Docker- Unable to find image “hello-world“locally问题描述一. 切换镜像1. 编辑镜像源2. 切换镜像内容 二、 检查设置1、 重启dockers2、 检查配置是否生效3. Docker镜像源检查4. Dokcer执行测试 三、自定义…...

spring-boot启动源码分析(二)之SpringApplicationRunListener

在上一篇《spring-boot启动源码分析&#xff08;一&#xff09;之SpringApplication实例构造》后&#xff0c;继续看了一个月的Spring boot启动源码&#xff0c;初步把流程看完了&#xff0c;接下来会不断输出总结&#xff0c;以巩固这段时间的学习。同时也希望能帮到同样感兴趣…...