URL時間戳參數深度解析:緩存破壞與前端優化的前世今生

🔍 URL時間戳參數深度解析:緩存破壞與前端優化的前世今生

在日常的Web開發中,你是否注意到很多接口URL后面都會帶有一個時間戳參數?比如 xxx/getMsg?_=1751413509056。這個看似簡單的參數背后,卻隱藏著前端緩存策略、性能優化等重要技術原理。今天,讓我們跟隨小李和小王的對話,深入探討這個參數的前世今生。


小李的困惑:神秘的URL參數

小李:小王,我最近在工作中發現一個奇怪的現象,很多接口的URL后面都會加一串類似于時間戳的東西,比如:xxx/getMsg?_=1751413509056。我在后端代碼中仔細檢查過,根本沒有處理這個參數的邏輯。這到底是怎么回事呢?

小王:哈哈,小李,你觀察得很仔細!這個參數確實不是給后端用的,而是前端用來解決緩存問題的一個巧妙技巧。讓我用3W法(What、Why、How)來給你詳細解釋一下。


What:什么是URL時間戳參數?

小李:那這個參數到底是什么呢?

小王:這個參數通常被稱為"緩存破壞參數"(Cache Busting Parameter)或"版本戳"(Version Stamp)。它的主要作用是:

  1. 強制刷新緩存:讓瀏覽器認為這是一個全新的請求
  2. 繞過瀏覽器緩存:確保獲取最新的資源內容
  3. 版本控制:標識資源的不同版本

常見的參數形式

// 時間戳形式
/api/data?_=1751413509056// 隨機數形式
/api/data?v=0.123456789// 版本號形式
/api/data?v=1.2.3// 哈希值形式
/api/data?v=a1b2c3d4

Why:為什么需要這個參數?

小李:既然有這個參數,那肯定是有原因的。為什么要這樣做呢?

小王:很好的問題!這涉及到Web緩存機制和前端性能優化的核心問題。讓我給你詳細分析:

1. 瀏覽器緩存機制

小王:現代瀏覽器都有強大的緩存機制,包括:

  • HTTP緩存:基于HTTP頭信息的緩存策略
  • 瀏覽器緩存:本地存儲的靜態資源
  • CDN緩存:分布式緩存網絡

2. 緩存帶來的問題

小李:緩存不是好事嗎?能提高性能啊!

小王:緩存確實能提高性能,但也會帶來一些問題:

// 問題場景示例
// 用戶訪問頁面,獲取數據
GET /api/userInfo
// 返回:{name: "張三", age: 25}// 數據更新后,用戶再次訪問
GET /api/userInfo  
// 瀏覽器返回緩存的舊數據:{name: "張三", age: 25}
// 而不是最新的:{name: "張三", age: 26}

3. 具體應用場景

小王:這個參數在以下場景中特別有用:

  1. API數據更新:后端數據發生變化,需要前端立即獲取最新數據
  2. 靜態資源更新:CSS、JS文件更新后,需要強制刷新
  3. 實時數據:股票、天氣等需要實時更新的數據
  4. 開發調試:開發過程中避免緩存干擾

How:如何實現和使用?

小李:那具體是怎么實現的呢?前端是怎么添加這個參數的?

小王:實現方式有很多種,我來給你展示幾種常見的做法:

1. JavaScript動態添加

// 方法1:使用時間戳
function addTimestamp(url) {const timestamp = new Date().getTime();const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}`;
}// 使用示例
const apiUrl = '/api/getMsg';
const urlWithTimestamp = addTimestamp(apiUrl);
// 結果:/api/getMsg?_=1751413509056

2. 使用隨機數

// 方法2:使用隨機數
function addRandomParam(url) {const random = Math.random();const separator = url.includes('?') ? '&' : '?';return `${url}${separator}v=${random}`;
}

3. 使用版本號

// 方法3:使用版本號(推薦用于生產環境)
const APP_VERSION = '1.2.3';function addVersionParam(url) {const separator = url.includes('?') ? '&' : '?';return `${url}${separator}v=${APP_VERSION}`;
}

4. 實際項目中的應用

小王:在實際項目中,通常會這樣使用:

// 封裝請求函數
class ApiClient {constructor() {this.baseUrl = '/api';}// 獲取數據(帶緩存破壞)async getData(endpoint, useCacheBusting = false) {let url = `${this.baseUrl}${endpoint}`;if (useCacheBusting) {url = this.addCacheBustingParam(url);}const response = await fetch(url);return response.json();}// 添加緩存破壞參數addCacheBustingParam(url) {const timestamp = Date.now();const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}`;}
}// 使用示例
const api = new ApiClient();// 普通請求(可能使用緩存)
api.getData('/userInfo');// 強制刷新請求
api.getData('/userInfo', true);

深入探討:時間戳參數的添加時機與代碼實現

小李:小王,你剛才說了很多實現方式,但我還是有點困惑。這些時間戳到底是誰添加進去的?什么時候添加進去的?我能在項目中看到相關的代碼嗎?

小王:很好的問題!這涉及到前端框架、庫和開發工具鏈的工作機制。讓我詳細給你分析一下:

1. 時間戳參數的添加者

小王:時間戳參數通常由以下幾個"角色"添加:

前端框架自動添加
// Vue.js 示例 - 在main.js中配置
import axios from 'axios';// 配置axios攔截器,自動添加時間戳
axios.interceptors.request.use(config => {// 為特定接口添加時間戳if (config.url.includes('/api/dynamic')) {config.url += (config.url.includes('?') ? '&' : '?') + '_=' + Date.now();}return config;
});
構建工具自動添加
// Webpack配置示例
module.exports = {output: {filename: '[name].[contenthash].js', // 基于內容哈希的文件名chunkFilename: '[name].[contenthash].js'},plugins: [new HtmlWebpackPlugin({template: './src/index.html',// 自動為靜態資源添加版本號hash: true})]
};
第三方庫自動添加
// jQuery Ajax示例
$.ajax({url: '/api/data',cache: false, // 自動添加時間戳參數success: function(data) {console.log(data);}
});// 實際發送的請求:/api/data?_=1751413509056

2. 添加時機分析

小李:那具體是在什么時候添加的呢?

小王:添加時機可以分為幾個層次:

開發時添加
// 開發環境中的手動添加
class DevelopmentApiClient {constructor() {this.isDev = process.env.NODE_ENV === 'development';}async request(url, options = {}) {if (this.isDev && options.forceRefresh) {// 開發環境強制刷新url = this.addTimestamp(url);}return fetch(url, options);}
}
運行時添加
// 運行時根據業務邏輯添加
class BusinessApiClient {async getUserProfile(userId) {let url = `/api/users/${userId}`;// 根據業務需求決定是否添加時間戳if (this.shouldForceRefresh(userId)) {url = this.addTimestamp(url);}return this.request(url);}shouldForceRefresh(userId) {// 業務邏輯:用戶信息更新后強制刷新const lastUpdate = this.getLastUpdateTime(userId);return Date.now() - lastUpdate > 5 * 60 * 1000; // 5分鐘}
}
構建時添加
// 構建工具配置
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {plugins: [new HtmlWebpackPlugin({template: './src/index.html',// 構建時自動添加版本號hash: true,// 或者使用時間戳inject: true,minify: {removeComments: true,collapseWhitespace: true}})]
};

3. 實際項目中的代碼位置

小李:那我在項目中具體能在哪些地方看到這些代碼呢?

小王:讓我給你一個完整的項目結構示例:

project/
├── src/
│   ├── utils/
│   │   └── api.js          # API請求封裝
│   ├── services/
│   │   └── userService.js  # 業務服務層
│   ├── config/
│   │   └── axios.js        # Axios配置
│   └── main.js             # 應用入口
├── webpack.config.js       # 構建配置
├── package.json
└── .env                    # 環境變量
具體代碼示例

1. API工具類 (src/utils/api.js)

// 緩存破壞工具類
export class CacheBuster {static addTimestamp(url) {const timestamp = Date.now();const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}`;}static addVersion(url, version) {const separator = url.includes('?') ? '&' : '?';return `${url}${separator}v=${version}`;}static addHash(url, hash) {const separator = url.includes('?') ? '&' : '?';return `${url}${separator}h=${hash}`;}
}// 基礎請求類
export class BaseApiClient {constructor(baseURL = '/api') {this.baseURL = baseURL;}async request(endpoint, options = {}) {const { useCacheBusting = false, cacheBustingType = 'timestamp' } = options;let url = `${this.baseURL}${endpoint}`;if (useCacheBusting) {switch (cacheBustingType) {case 'timestamp':url = CacheBuster.addTimestamp(url);break;case 'version':url = CacheBuster.addVersion(url, process.env.APP_VERSION);break;case 'hash':url = CacheBuster.addHash(url, this.generateHash());break;}}const response = await fetch(url, options);return response.json();}generateHash() {return Math.random().toString(36).substr(2, 9);}
}

2. Axios配置 (src/config/axios.js)

import axios from 'axios';// 創建axios實例
const api = axios.create({baseURL: process.env.REACT_APP_API_BASE_URL || '/api',timeout: 10000
});// 請求攔截器
api.interceptors.request.use(config => {// 開發環境自動添加時間戳if (process.env.NODE_ENV === 'development') {config.url = addTimestampIfNeeded(config.url);}// 特定接口強制刷新if (config.forceRefresh) {config.url = addTimestamp(config.url);}return config;},error => {return Promise.reject(error);}
);// 響應攔截器
api.interceptors.response.use(response => {return response;},error => {// 如果是緩存相關錯誤,重試時添加時間戳if (error.response?.status === 304) {const originalRequest = error.config;originalRequest.url = addTimestamp(originalRequest.url);return api(originalRequest);}return Promise.reject(error);}
);function addTimestamp(url) {const timestamp = Date.now();const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}`;
}function addTimestampIfNeeded(url) {// 只對特定接口添加時間戳const dynamicEndpoints = ['/user/profile', '/data/realtime', '/config/latest'];const shouldAdd = dynamicEndpoints.some(endpoint => url.includes(endpoint));if (shouldAdd) {return addTimestamp(url);}return url;
}export default api;

3. 業務服務層 (src/services/userService.js)

import api from '../config/axios';export class UserService {// 獲取用戶基本信息(使用緩存)async getUserInfo(userId) {return api.get(`/users/${userId}`);}// 獲取用戶實時數據(強制刷新)async getUserRealTimeData(userId) {return api.get(`/users/${userId}/realtime`, {forceRefresh: true});}// 更新用戶信息后刷新async updateUserInfo(userId, userData) {await api.put(`/users/${userId}`, userData);// 更新后強制刷新用戶信息return this.getUserInfo(userId, { forceRefresh: true });}// 獲取用戶配置(根據配置類型決定是否刷新)async getUserConfig(userId, configType) {const isDynamicConfig = ['preferences', 'settings'].includes(configType);return api.get(`/users/${userId}/config/${configType}`, {forceRefresh: isDynamicConfig});}
}

4. 參數名的選擇與規范

小李:小王,我注意到你剛才的代碼中參數名用的是 _,這個參數名有特殊要求嗎?我看有些地方用的是 vt 或者其他名字,有什么講究嗎?

小王:很好的觀察!參數名的選擇確實有一些歷史原因和最佳實踐,讓我詳細給你解釋一下:

常見的參數名及其含義
// 1. 下劃線 (_) - 最常用的選擇
/api/data?_=1751413509056// 2. 版本號 (v) - 語義化版本控制
/api/data?v=1.2.3// 3. 時間戳 (t) - 明確表示時間
/api/data?t=1751413509056// 4. 哈希值 (h) - 內容哈希
/api/data?h=a1b2c3d4// 5. 隨機數 (r) - 隨機標識
/api/data?r=0.123456789// 6. 緩存破壞 (cb) - Cache Busting縮寫
/api/data?cb=1751413509056
為什么選擇下劃線 (_)?

小王:下劃線作為參數名有以下幾個優勢:

  1. 簡潔性:單個字符,URL更短
  2. 通用性:幾乎所有編程語言都支持
  3. 歷史原因:早期Web開發中的約定俗成
  4. 避免沖突:不太可能與業務參數沖突
// 參數名對比示例
// ? 可能沖突的參數名
/api/user?name=張三&id=123&version=1.0  // version可能與業務參數沖突// ? 使用下劃線避免沖突
/api/user?name=張三&id=123&_=1751413509056  // 下劃線不會與業務參數沖突
不同場景的參數名選擇

小王:根據不同的使用場景,可以選擇不同的參數名:

// 1. 開發環境 - 使用時間戳
class DevelopmentCacheBuster {static addParam(url) {const timestamp = Date.now();const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}`;}
}// 2. 生產環境 - 使用版本號
class ProductionCacheBuster {static addParam(url) {const version = process.env.APP_VERSION || '1.0.0';const separator = url.includes('?') ? '&' : '?';return `${url}${separator}v=${version}`;}
}// 3. 內容哈希 - 用于靜態資源
class ContentHashCacheBuster {static addParam(url, contentHash) {const separator = url.includes('?') ? '&' : '?';return `${url}${separator}h=${contentHash}`;}
}// 4. 語義化參數名 - 明確表達意圖
class SemanticCacheBuster {static addParam(url, type = 'timestamp') {const separator = url.includes('?') ? '&' : '?';switch (type) {case 'timestamp':return `${url}${separator}t=${Date.now()}`;case 'version':return `${url}${separator}v=${process.env.APP_VERSION}`;case 'random':return `${url}${separator}r=${Math.random()}`;default:return `${url}${separator}_=${Date.now()}`;}}
}
參數名的最佳實踐

小王:在實際項目中,建議遵循以下規范:

// 統一的緩存破壞工具類
class CacheBuster {// 配置參數名策略static config = {development: '_',    // 開發環境用下劃線production: 'v',     // 生產環境用版本號static: 'h',         // 靜態資源用哈希dynamic: 't'         // 動態數據用時間戳};static addParam(url, type = 'development') {const paramName = this.config[type];const separator = url.includes('?') ? '&' : '?';let paramValue;switch (type) {case 'development':paramValue = Date.now();break;case 'production':paramValue = process.env.APP_VERSION || '1.0.0';break;case 'static':paramValue = this.generateContentHash(url);break;case 'dynamic':paramValue = Date.now();break;default:paramValue = Date.now();}return `${url}${separator}${paramName}=${paramValue}`;}static generateContentHash(url) {// 簡化的內容哈希生成return Math.random().toString(36).substr(2, 8);}
}// 使用示例
const api = {// 開發環境APIdev: (url) => CacheBuster.addParam(url, 'development'),// 生產環境APIprod: (url) => CacheBuster.addParam(url, 'production'),// 靜態資源static: (url) => CacheBuster.addParam(url, 'static'),// 動態數據dynamic: (url) => CacheBuster.addParam(url, 'dynamic')
};
參數名的安全性考慮

小李:那參數名會不會有安全風險呢?

小王:確實需要考慮一些安全因素:

// 安全考慮示例
class SecureCacheBuster {static addParam(url, options = {}) {const {paramName = '_',sanitize = true,maxLength = 20} = options;// 參數名安全檢查if (sanitize && !this.isValidParamName(paramName)) {throw new Error('Invalid parameter name');}const separator = url.includes('?') ? '&' : '?';const value = this.generateSecureValue(maxLength);return `${url}${separator}${paramName}=${value}`;}static isValidParamName(name) {// 只允許字母、數字、下劃線return /^[a-zA-Z0-9_]+$/.test(name);}static generateSecureValue(maxLength) {// 生成安全的隨機值return Math.random().toString(36).substr(2, maxLength);}
}
實際項目中的參數名規范

小王:在大型項目中,通常會制定統一的參數名規范:

// 項目配置文件
const CACHE_BUSTING_CONFIG = {// 開發環境development: {api: '_',           // API請求static: 'v',        // 靜態資源dynamic: 't'        // 動態數據},// 生產環境production: {api: 'v',           // API請求用版本號static: 'h',        // 靜態資源用哈希dynamic: 't'        // 動態數據用時間戳},// 測試環境testing: {api: 'cb',          // Cache Busting縮寫static: 'v',dynamic: 't'}
};// 統一的緩存破壞服務
class CacheBustingService {constructor(environment = 'development') {this.config = CACHE_BUSTING_CONFIG[environment];}addParam(url, type = 'api') {const paramName = this.config[type];const separator = url.includes('?') ? '&' : '?';const value = this.generateValue(type);return `${url}${separator}${paramName}=${value}`;}generateValue(type) {switch (type) {case 'api':return Date.now();case 'static':return process.env.APP_VERSION || '1.0.0';case 'dynamic':return Date.now();default:return Date.now();}}
}

5. 調試和監控

小李:那我在開發時怎么調試這些參數呢?

小王:有幾種方法可以調試和監控:

瀏覽器開發者工具
// 在控制臺中監控請求
const originalFetch = window.fetch;
window.fetch = function(...args) {console.log('Fetch請求:', args[0]);return originalFetch.apply(this, args);
};// 監控XMLHttpRequest
const originalXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...args) {console.log('XHR請求:', url);return originalXHROpen.apply(this, [method, url, ...args]);
};
網絡面板分析
// 在代碼中添加調試信息
class DebugApiClient extends BaseApiClient {async request(endpoint, options = {}) {const originalUrl = `${this.baseURL}${endpoint}`;const finalUrl = options.useCacheBusting ? CacheBuster.addTimestamp(originalUrl) : originalUrl;console.log('API請求:', {original: originalUrl,final: finalUrl,hasCacheBusting: options.useCacheBusting});return super.request(endpoint, options);}
}

深入理解:緩存策略與HTTP頭

小李:小王,你剛才提到了HTTP緩存,能詳細說說嗎?

小王:當然可以!這涉及到HTTP緩存控制機制,讓我給你詳細解釋:

HTTP緩存控制頭

# 服務器響應頭示例
HTTP/1.1 200 OK
Cache-Control: max-age=3600
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT

緩存策略對比

策略優點缺點適用場景
時間戳參數簡單直接,強制刷新每次都請求,浪費帶寬數據更新頻繁
HTTP緩存頭智能緩存,節省帶寬配置復雜,需要服務器支持靜態資源,數據穩定
ETag機制精確控制,節省帶寬需要服務器計算ETag大型應用

實際案例分析

小王:讓我用一個實際的例子來說明:

// 場景:用戶管理系統
class UserManager {constructor() {this.api = new ApiClient();}// 獲取用戶列表(使用緩存)async getUserList() {return await this.api.getData('/users');}// 獲取用戶詳情(強制刷新)async getUserDetail(userId) {return await this.api.getData(`/users/${userId}`, true);}// 更新用戶信息后,強制刷新列表async updateUser(userId, userData) {await this.api.postData(`/users/${userId}`, userData);// 更新后強制刷新用戶列表return await this.getUserList(true);}
}

最佳實踐與注意事項

小李:那在實際開發中,有什么最佳實踐嗎?

小王:確實有一些重要的最佳實踐需要注意:

1. 合理使用緩存破壞

// ? 錯誤做法:所有請求都加時間戳
function badPractice() {// 每次都強制刷新,浪費帶寬fetch('/api/staticData?_=' + Date.now());
}// ? 正確做法:根據數據特性決定
function goodPractice() {// 靜態數據使用緩存fetch('/api/staticData');// 動態數據強制刷新fetch('/api/dynamicData?_=' + Date.now());
}

2. 版本號管理

// 生產環境推薦使用版本號而不是時間戳
const config = {development: {cacheBusting: 'timestamp'  // 開發環境用時間戳},production: {cacheBusting: 'version'    // 生產環境用版本號}
};

3. 性能考慮

小王:使用時間戳參數時要注意性能影響:

// 性能優化示例
class OptimizedApiClient {constructor() {this.cache = new Map();this.cacheTimeout = 5 * 60 * 1000; // 5分鐘}async getData(url, useCacheBusting = false) {const cacheKey = `${url}_${useCacheBusting}`;// 檢查內存緩存if (this.cache.has(cacheKey)) {const cached = this.cache.get(cacheKey);if (Date.now() - cached.timestamp < this.cacheTimeout) {return cached.data;}}// 發起請求let requestUrl = url;if (useCacheBusting) {requestUrl = this.addCacheBustingParam(url);}const response = await fetch(requestUrl);const data = await response.json();// 緩存結果this.cache.set(cacheKey, {data,timestamp: Date.now()});return data;}
}

常見問題與解決方案

小李:小王,我在使用過程中遇到了一些問題,能幫我解決嗎?

小王:當然可以!讓我總結一下常見問題和解決方案:

問題1:參數名沖突

// 問題:URL中已有同名參數
const url = '/api/data?param1=value1&_=123';// 解決方案:檢查并處理
function addCacheBustingParam(url) {const timestamp = Date.now();if (url.includes('_=')) {// 替換現有的時間戳參數return url.replace(/_[^&]*/, `_=${timestamp}`);} else {const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}`;}
}

問題2:CDN緩存

// CDN緩存問題:即使加了時間戳,CDN可能仍然緩存
// 解決方案:使用更復雜的緩存破壞策略function advancedCacheBusting(url) {const timestamp = Date.now();const random = Math.random().toString(36).substr(2, 9);const separator = url.includes('?') ? '&' : '?';return `${url}${separator}_=${timestamp}&r=${random}`;
}

問題3:SEO影響

// SEO問題:搜索引擎可能將帶時間戳的URL視為不同頁面
// 解決方案:區分靜態資源和動態數據// 靜態資源使用版本號
const staticAssets = {css: '/assets/style.css?v=1.2.3',js: '/assets/app.js?v=1.2.3'
};// 動態數據使用時間戳
const apiEndpoints = {userData: '/api/user?_=' + Date.now()
};

總結與展望

小李:小王,今天學到了很多!讓我總結一下:

  1. URL時間戳參數是前端用來破壞緩存的技術手段
  2. 主要作用是強制瀏覽器獲取最新數據
  3. 實現方式包括時間戳、隨機數、版本號等
  4. 需要合理使用,避免過度使用影響性能

小王:總結得很好!補充一點,隨著技術的發展,現在有更多現代化的解決方案:

現代替代方案

  1. Service Worker:更精細的緩存控制
  2. HTTP/2 Server Push:服務器主動推送更新
  3. WebSocket:實時數據推送
  4. GraphQL:精確的數據查詢和緩存

未來趨勢

// 現代緩存策略示例
class ModernCacheStrategy {constructor() {this.serviceWorker = null;this.initServiceWorker();}async initServiceWorker() {if ('serviceWorker' in navigator) {this.serviceWorker = await navigator.serviceWorker.register('/sw.js');}}// 使用Service Worker進行緩存控制async getDataWithModernCache(url) {// 實現更智能的緩存策略}
}

結語

通過今天的對話,我們深入了解了URL時間戳參數的前世今生。這個看似簡單的技術細節,實際上體現了Web開發中緩存策略、性能優化、用戶體驗等多個方面的考慮。

在實際開發中,我們需要根據具體場景選擇合適的緩存策略,既要保證數據的實時性,又要兼顧性能和用戶體驗。希望今天的分享能幫助你在工作中更好地處理類似問題!


本文采用對話形式,通過小李和小王的問答,深入淺出地講解了URL時間戳參數的技術原理和應用實踐。如果你有更多問題或想法,歡迎繼續探討!

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

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

相關文章

分布式鎖實現方式:基于Redis的分布式鎖實現(Spring Boot + Redis)

Redis實現分布式鎖的原理 Redis分布式鎖基于其單線程執行命令的特性&#xff0c;通過原子操作實現多節點間的互斥訪問。下面從原理、實現、問題及優化四個方面詳細解析&#xff1a; 1.原子性與互斥性 Redis分布式鎖的核心是原子性操作&#xff1a; 獲取鎖&#xff1a;使用SE…

linux升級降級內核實驗

?實驗環境 vmware workstation 17 centos7.9 下載鏈接&#xff1a; https://vault.centos.org/7.9.2009/isos/x86_64/ ubuntu24.04 下載鏈接&#xff1a; https://old-releases.ubuntu.com/releases/24.04/ ?實驗目的 為了解決日常環境部署中某些驅動軟件依賴特定內…

華為云開始了“開發者空間 AI Agent 開發”活動

引言 今天在華為云App上偶然看到一個新活動&#xff1a;Developer Events_Developer Alliance-Huawei Cloud。這個活動要求開發者可結合自己的工作實踐&#xff0c;須在華為開發者空間內完成應用構建&#xff0c;應用構建類型和主題為AI Agent應用開發。 AI Agent平臺 華為開…

2025.6.26總結

今天和我做同一業務得同事進行了工作交接&#xff0c;主要給我講了怎么去執行自動化。包括性能自動化&#xff0c;API自動化&#xff0c;UI自動化&#xff0c;除了UI自動化要寫些代碼&#xff0c;其他跑得話也就在工具上配個參數&#xff0c;就是個搬磚得活&#xff0c;沒太大技…

ip網絡基礎

交換機工作原理&#xff1a; 自主學習mac地址并成mac地址表 根據mac地址表再進行單播、廣播轉發 主機通信原理&#xff08;局域網&#xff09;&#xff1a; 需要了解arp協議 拓撲圖&#xff1a; 首先&#xff0c;我們觀察icmp數據包&#xff0c;發現缺少目標mac地址&#…

AI大模型如何重塑軟件開發流程?

文章目錄 每日一句正能量前言一、AI大模型的定義與特點&#xff08;一&#xff09;定義&#xff08;二&#xff09;特點 二、AI大模型在軟件開發中的應用場景&#xff08;一&#xff09;代碼自動生成&#xff08;二&#xff09;智能測試&#xff08;三&#xff09;需求分析與設…

Kafka與RabbitMQ相比有什么優勢?

大家好&#xff0c;我是鋒哥。今天分享關于【Kafka與RabbitMQ相比有什么優勢&#xff1f;】面試題。希望對大家有幫助&#xff1b; Kafka與RabbitMQ相比有什么優勢&#xff1f; 超硬核AI學習資料&#xff0c;現在永久免費了&#xff01; Kafka與RabbitMQ在消息隊列的設計和應…

LeetCode 2090. 半徑為 k 的子數組平均值

題目鏈接 2090. 半徑為 k 的子數組平均值 題目描述 給定一個下標從 0 開始的整數數組 nums 和整數 k&#xff0c;構建并返回一個長度為 n 的數組 avgs&#xff0c;其中 avgs[i] 表示以下標 i 為中心、半徑為 k 的子數組的平均值。具體規則如下&#xff1a; 無效位置&#x…

深入理解C++11原子操作:從內存模型到無鎖編程

文章目錄 C并發編程的新紀元內存模型基礎&#xff1a;可見性與有序性數據競爭的根源happens-before關系memory_order枚舉詳解1. memory_order_relaxed2. memory_order_acquire/memory_order_release3. memory_order_seq_cst 原子操作詳解std::atomic模板核心原子操作1. 讀取與存…

DQL-1-基礎查詢

基礎查詢 DQL-1-基礎查詢 基礎查詢DQL - 介紹DQL - 語法DQL - 基本查詢案例 DQL - 介紹 SQL 英文全稱是 Data Query Language, 數據查詢語言, 用來查詢數據庫中表的記錄 查詢關鍵字: SELECT DQL - 語法 SELECT 字段列表FROM 表名列表WHERE條件列表GROUP BY分組字段列表HAVI…

Prompt 精通之路(七)- 你的終極 AI 寶典:Prompt 精通之路系列匯總

你的終極 AI 寶典&#xff1a;Prompt 精通之路系列匯總 標簽&#xff1a; #Prompt指南 #AI學習資源 #速查手冊 #ChatGPT #系列總結 &#x1f680; Prompt 精通之路&#xff1a;系列文章導航 第一篇&#xff1a;AI 時代的新語言&#xff1a;到底什么是 Prompt&#xff1f;為什么…

P27:RNN實現阿爾茨海默病診斷

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 一、過程解讀 PyTorch 實戰&#xff1a;阿爾茨海默病數據預測模型 今天&#xff0c;我將帶大家一起探索一個基于 PyTorch 的深度學習小項目——利用 RNN 模…

HakcMyVM-Arroutada

信息搜集 主機發現 ┌──(kali?kali)-[~] └─$ nmap -sn 192.168.21.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-01 07:13 EDT Nmap scan report for 192.168.21.11 Host is up (0.00062s latency). MAC Address: 08:00:27:4E:CC:FB (PCS Systemtechnik/Or…

TEXT Submitting Solutions

前言 USACO 訓練項目配備了一個自動評分系統&#xff0c;用于批改你的作業題目。你可以直接在題目頁面提交你的程序&#xff1b;系統會對程序進行編譯和評分&#xff0c;幾秒鐘內就能將結果反饋給你。 支持的語言有 C、C&#xff08;含 C11 和 C14&#xff09;、PASCAL、Pyth…

Reactor 瞬態錯誤

在響應式編程中&#xff0c;retryWhen 操作符通過 RetrySignal 接口提供了對重試行為的精細控制&#xff0c;特別是在處理 瞬態錯誤&#xff08;transient errors&#xff09; 時。瞬態錯誤是指那些在一段時間內發生&#xff0c;但隨后會自行恢復的錯誤&#xff0c;例如網絡請求…

基于 SpringBoot+Vue.js+ElementUI 的小型超市商品管理系統設計與實現7000字論文設計

摘要 本論文設計并實現了一個基于 SpringBoot、Vue.js 和 ElementUI 的小型超市商品管理系統。該系統旨在為小型超市提供一個高效、便捷的商品管理解決方案&#xff0c;實現商品信息的錄入、查詢、修改、刪除等功能&#xff0c;同時支持庫存管理、銷售統計等業務需求。論文首先…

Kerberos 認證協議解析

文章目錄 概述核心概念認證流程階段一&#xff1a;Client -> AS&#xff0c;獲取 TGT階段二&#xff1a;Client -> TGS&#xff0c;獲取服務票據階段三&#xff1a;Client -> Server&#xff0c;請求服務 核心安全機制優缺點分析優勢局限性 實踐與排錯關鍵配置 (krb5.…

【設計模式07】適配器

前言 實現目標&#xff0c;組合源&#xff0c;寫個適配方法&#xff0c;適用于沒辦法改變源&#xff0c;但又想實現目標類。我暫時還沒使用到過&#xff0c;但感覺用處還是蠻大的 UML類圖 代碼示例 package com.sw.learn.pattern.C_structre.a_adapter;public class Main {//…

SPI、I2C和UART三種串行通信協議的--------簡單總結

目錄 一、3種協議的對比二、典型應用場景三、選型建議 以下是SPI、I2C和UART三種串行通信協議的對比分析及適用場景總結&#xff1a; 一、3種協議的對比 . 對比其他接口 特性ICSPIUART信號線數量2&#xff08;SCL SDA&#xff09;4&#xff08;SCK MOSI MISO SS/CS&…

VUE admin-element 后臺管理系統三級菜單實現緩存

VUE admin-element 后臺管理系統三級菜單實現緩存 框架無法直接實現三級菜單頁面緩存&#xff0c;原因是由于直接緩存時沒有把上級路由文件名稱緩存進去&#xff0c;所以在框架基礎上參考部分文章進行了一些改造 菜單文件&#xff0c;三級菜單引用文件路徑修改&#xff0c;在…