代理模式實戰指南:打造高性能RPC調用與智能圖片加載系統

代理模式實戰指南:打造高性能RPC調用與智能圖片加載系統


🌟 嗨,我是IRpickstars!

🌌 總有一行代碼,能點亮萬千星辰。

🔍 在技術的宇宙中,我愿做永不停歇的探索者。

? 用代碼丈量世界,用算法解碼未來。我是摘星人,也是造夢者。

🚀 每一次編譯都是新的征程,每一個bug都是未解的謎題。讓我們攜手,在0和1的星河中,書寫屬于開發者的浪漫詩篇。


目錄

代理模式實戰指南:打造高性能RPC調用與智能圖片加載系統

摘要

代理模式概述與發展歷程

什么是代理模式

UML類圖結構

發展歷程

代理模式的四種主要類型

1. 虛擬代理(Virtual Proxy)

2. 遠程代理(Remote Proxy)

3. 保護代理(Protection Proxy)

4. 智能代理(Smart Proxy)

遠程服務調用中的代理應用

RPC框架中的代理機制

1. Spring Cloud Feign的代理實現

2. RPC調用流程圖

3. 動態代理在RPC中的應用

懶加載圖片的虛擬代理實現

前端圖片懶加載的核心需求

TypeScript實現的圖片懶加載代理

圖片懶加載時序圖

CSS樣式支持

代理模式的最佳實踐與對比分析

代理模式 vs 裝飾器模式 vs 適配器模式

Spring AOP中的代理應用

性能優化建議

結語與展望


?

摘要

作為一名在軟件開發領域深耕多年的技術人員,我深深感受到設計模式在現代軟件架構中的重要價值,特別是代理模式。在我的實際項目經驗中,代理模式幾乎無處不在——從微服務架構中的RPC調用,到前端性能優化中的圖片懶加載,再到Spring框架的AOP實現,代理模式都扮演著至關重要的角色。

在當今云原生和微服務盛行的時代,系統的復雜性日益增加,我們需要更加優雅的方式來處理遠程服務調用、資源管理和訪問控制。代理模式提供了一種在不改變原有對象結構的前提下,為其他對象提供一種代理以控制對這個對象的訪問的解決方案。這種"中間層"的設計思想,讓我們能夠在保持系統松耦合的同時,實現諸如緩存、安全檢查、延遲加載等橫切關注點。

在我參與的分布式系統項目中,RPC代理幫助我們屏蔽了遠程調用的復雜性,讓開發者能夠像調用本地方法一樣調用遠程服務。而在前端性能優化實踐中,圖片懶加載的虛擬代理模式讓我們的頁面加載速度提升了40%以上。這些實實在在的收益,讓我對代理模式有了更深的理解和認識。

代理模式概述與發展歷程

什么是代理模式

代理模式(Proxy Pattern)是一種結構型設計模式,它為其他對象提供一種代理以控制對這個對象的訪問。代理對象在客戶端和目標對象之間起到中介的作用,可以在不修改目標對象的前提下,擴展目標對象的功能。

UML類圖結構

圖1:代理模式UML類圖

發展歷程

代理模式的概念最早可以追溯到1994年GoF的《設計模式》一書,但其思想在計算機科學中的應用更為久遠。從最初的內存管理代理,到網絡通信中的代理服務器,再到現代的微服務代理,這種模式經歷了不斷的演進和發展。

代理模式的四種主要類型

1. 虛擬代理(Virtual Proxy)

用于控制對創建開銷很大的對象的訪問,延遲對象的創建直到真正需要時。典型應用:圖片懶加載、大文件下載。

2. 遠程代理(Remote Proxy)

為位于不同地址空間的對象提供本地代表,隱藏對象存在于不同地址空間的事實。典型應用:RPC調用、Web服務代理。

3. 保護代理(Protection Proxy)

控制對原始對象的訪問,提供訪問權限控制。典型應用:權限驗證、安全檢查。

4. 智能代理(Smart Proxy)

在訪問對象時執行一些附加操作,如引用計數、緩存、日志記錄等。典型應用:緩存代理、日志代理。

遠程服務調用中的代理應用

RPC框架中的代理機制

在現代分布式系統中,RPC(Remote Procedure Call)框架廣泛使用代理模式來簡化遠程服務調用。讓我們深入分析幾個主流框架的實現:

1. Spring Cloud Feign的代理實現
/*** Feign客戶端接口定義* 通過注解聲明遠程服務調用*/
@FeignClient(name = "user-service", url = "http://localhost:8080")
public interface UserServiceClient {@GetMapping("/users/{id}")UserDTO getUserById(@PathVariable("id") Long id);@PostMapping("/users")UserDTO createUser(@RequestBody CreateUserRequest request);
}/*** 自定義RPC代理實現* 展示代理模式在RPC調用中的核心機制*/
public class RpcProxy implements InvocationHandler {private final String serviceName;private final String serviceUrl;private final HttpClient httpClient;private final ObjectMapper objectMapper;public RpcProxy(String serviceName, String serviceUrl) {this.serviceName = serviceName;this.serviceUrl = serviceUrl;this.httpClient = HttpClient.newHttpClient();this.objectMapper = new ObjectMapper();}/*** 代理方法調用的核心邏輯* 將本地方法調用轉換為遠程HTTP請求*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 1. 預處理:構建請求參數RpcRequest request = buildRequest(method, args);// 2. 執行遠程調用try {RpcResponse response = executeRemoteCall(request);// 3. 后處理:解析響應結果return parseResponse(response, method.getReturnType());} catch (Exception e) {// 4. 異常處理:重試、降級等策略return handleException(e, method);}}/*** 構建RPC請求對象*/private RpcRequest buildRequest(Method method, Object[] args) {RpcRequest request = new RpcRequest();request.setServiceName(serviceName);request.setMethodName(method.getName());request.setParameterTypes(method.getParameterTypes());request.setParameters(args);request.setRequestId(UUID.randomUUID().toString());return request;}/*** 執行遠程HTTP調用*/private RpcResponse executeRemoteCall(RpcRequest request) throws Exception {String requestBody = objectMapper.writeValueAsString(request);HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create(serviceUrl + "/rpc")).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody)).timeout(Duration.ofSeconds(30)).build();HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());if (response.statusCode() != 200) {throw new RpcException("Remote call failed: " + response.statusCode());}return objectMapper.readValue(response.body(), RpcResponse.class);}/*** 解析遠程調用響應*/private Object parseResponse(RpcResponse response, Class<?> returnType) throws Exception {if (response.hasError()) {throw new RpcException(response.getErrorMessage());}if (returnType == void.class) {return null;}return objectMapper.convertValue(response.getResult(), returnType);}/*** 異常處理策略*/private Object handleException(Exception e, Method method) {// 記錄日志log.error("RPC call failed for method: {}, error: {}", method.getName(), e.getMessage());// 降級策略:返回默認值或拋出業務異常if (method.getReturnType() == String.class) {return "DEFAULT_VALUE";}throw new RuntimeException("Service unavailable", e);}
}/*** 代理工廠類* 負責創建和管理RPC代理實例*/
public class RpcProxyFactory {private final Map<String, Object> proxyCache = new ConcurrentHashMap<>();/*** 創建RPC代理實例*/@SuppressWarnings("unchecked")public <T> T createProxy(Class<T> serviceInterface, String serviceName, String serviceUrl) {String cacheKey = serviceName + ":" + serviceInterface.getName();return (T) proxyCache.computeIfAbsent(cacheKey, key -> {return Proxy.newProxyInstance(serviceInterface.getClassLoader(),new Class<?>[]{serviceInterface},new RpcProxy(serviceName, serviceUrl));});}
}/*** 使用示例*/
public class RpcClientExample {public static void main(String[] args) {RpcProxyFactory factory = new RpcProxyFactory();// 創建用戶服務代理UserServiceClient userService = factory.createProxy(UserServiceClient.class, "user-service", "http://localhost:8080");// 像調用本地方法一樣調用遠程服務try {UserDTO user = userService.getUserById(1L);System.out.println("Retrieved user: " + user.getName());CreateUserRequest request = new CreateUserRequest("John Doe", "john@example.com");UserDTO newUser = userService.createUser(request);System.out.println("Created user: " + newUser.getId());} catch (Exception e) {System.err.println("RPC call failed: " + e.getMessage());}}
}
2. RPC調用流程圖

圖2:RPC調用流程圖

3. 動態代理在RPC中的應用

在Java生態中,RPC框架主要使用兩種動態代理技術:

JDK動態代理:適用于基于接口的代理,如Feign、Dubbo接口代理
CGLIB代理:適用于基于類的代理,可以代理沒有接口的類

/*** CGLIB代理示例* 用于代理具體類而非接口*/
public class CglibRpcProxy implements MethodInterceptor {private final String serviceUrl;public CglibRpcProxy(String serviceUrl) {this.serviceUrl = serviceUrl;}@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {// 跳過Object類的基礎方法if (method.getDeclaringClass() == Object.class) {return proxy.invokeSuper(obj, args);}// 執行遠程調用邏輯return executeRemoteCall(method, args);}private Object executeRemoteCall(Method method, Object[] args) {// 遠程調用實現...return null;}/*** 創建CGLIB代理實例*/public static <T> T createProxy(Class<T> targetClass, String serviceUrl) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(targetClass);enhancer.setCallback(new CglibRpcProxy(serviceUrl));return (T) enhancer.create();}
}

懶加載圖片的虛擬代理實現

前端圖片懶加載的核心需求

在現代Web應用中,圖片資源往往占據了頁面總大小的很大比例。傳統的圖片加載方式會在頁面初始化時加載所有圖片,這不僅增加了首屏加載時間,還浪費了用戶的帶寬資源。虛擬代理模式為我們提供了優雅的解決方案。

TypeScript實現的圖片懶加載代理

/*** 圖片接口定義*/
interface ImageInterface {display(): void;load(): Promise<void>;isLoaded(): boolean;
}/*** 真實圖片類* 負責實際的圖片加載和顯示邏輯*/
class RealImage implements ImageInterface {private filename: string;private element: HTMLImageElement;private loaded: boolean = false;private loading: boolean = false;constructor(filename: string, element: HTMLImageElement) {this.filename = filename;this.element = element;}/*** 異步加載圖片*/async load(): Promise<void> {if (this.loaded || this.loading) {return;}this.loading = true;try {// 顯示加載占位符this.showLoadingPlaceholder();// 預加載圖片await this.preloadImage();// 設置圖片源并顯示this.element.src = this.filename;this.element.classList.remove('loading');this.element.classList.add('loaded');this.loaded = true;console.log(`Image loaded: ${this.filename}`);} catch (error) {console.error(`Failed to load image: ${this.filename}`, error);this.showErrorPlaceholder();} finally {this.loading = false;}}/*** 顯示圖片(如果已加載)*/display(): void {if (this.loaded) {this.element.style.display = 'block';}}isLoaded(): boolean {return this.loaded;}/*** 預加載圖片的私有方法*/private preloadImage(): Promise<void> {return new Promise((resolve, reject) => {const img = new Image();img.onload = () => resolve();img.onerror = () => reject(new Error('Image load failed'));// 設置超時處理setTimeout(() => reject(new Error('Image load timeout')), 10000);img.src = this.filename;});}/*** 顯示加載占位符*/private showLoadingPlaceholder(): void {this.element.classList.add('loading');this.element.style.backgroundColor = '#f0f0f0';this.element.style.display = 'block';}/*** 顯示錯誤占位符*/private showErrorPlaceholder(): void {this.element.classList.remove('loading');this.element.classList.add('error');this.element.style.backgroundColor = '#ffebee';}
}/*** 圖片代理類* 實現虛擬代理模式,控制圖片的延遲加載*/
class ImageProxy implements ImageInterface {private realImage: RealImage | null = null;private filename: string;private element: HTMLImageElement;private observer: IntersectionObserver | null = null;constructor(filename: string, element: HTMLImageElement) {this.filename = filename;this.element = element;this.initializeProxy();}/*** 初始化代理,設置占位符和觀察器*/private initializeProxy(): void {// 設置占位符圖片this.setPlaceholder();// 設置Intersection Observer用于檢測元素可見性this.setupIntersectionObserver();}/*** 設置占位符*/private setPlaceholder(): void {// 生成SVG占位符const placeholder = this.generatePlaceholderSvg();this.element.src = `data:image/svg+xml;base64,${btoa(placeholder)}`;this.element.classList.add('lazy-image');this.element.setAttribute('data-src', this.filename);}/*** 生成SVG占位符*/private generatePlaceholderSvg(): string {const width = this.element.width || 300;const height = this.element.height || 200;return `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="#f0f0f0"/><text x="50%" y="50%" font-family="Arial, sans-serif" font-size="14" fill="#999" text-anchor="middle" dy=".3em">Loading...</text></svg>`;}/*** 設置Intersection Observer*/private setupIntersectionObserver(): void {const options: IntersectionObserverInit = {root: null, // 使用視口作為根rootMargin: '50px', // 提前50px開始加載threshold: 0.1 // 當10%的元素可見時觸發};this.observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {this.load();this.observer?.unobserve(this.element);}});}, options);this.observer.observe(this.element);}/*** 異步加載真實圖片*/async load(): Promise<void> {if (!this.realImage) {this.realImage = new RealImage(this.filename, this.element);}await this.realImage.load();}/*** 顯示圖片*/display(): void {if (this.realImage) {this.realImage.display();}}/*** 檢查圖片是否已加載*/isLoaded(): boolean {return this.realImage ? this.realImage.isLoaded() : false;}/*** 清理資源*/destroy(): void {if (this.observer) {this.observer.unobserve(this.element);this.observer.disconnect();}}
}/*** 圖片懶加載管理器* 統一管理頁面中的所有懶加載圖片*/
class LazyImageManager {private imageProxies: Map<HTMLImageElement, ImageProxy> = new Map();private mutationObserver: MutationObserver;constructor() {this.initializeMutationObserver();this.processExistingImages();}/*** 初始化DOM變化觀察器*/private initializeMutationObserver(): void {this.mutationObserver = new MutationObserver((mutations) => {mutations.forEach(mutation => {mutation.addedNodes.forEach(node => {if (node.nodeType === Node.ELEMENT_NODE) {this.processElement(node as Element);}});});});this.mutationObserver.observe(document.body, {childList: true,subtree: true});}/*** 處理頁面中已存在的圖片*/private processExistingImages(): void {const images = document.querySelectorAll('img[data-lazy]');images.forEach(img => this.processImage(img as HTMLImageElement));}/*** 處理DOM元素,查找需要懶加載的圖片*/private processElement(element: Element): void {if (element.tagName === 'IMG' && element.hasAttribute('data-lazy')) {this.processImage(element as HTMLImageElement);}const images = element.querySelectorAll('img[data-lazy]');images.forEach(img => this.processImage(img as HTMLImageElement));}/*** 為圖片創建代理*/private processImage(img: HTMLImageElement): void {if (this.imageProxies.has(img)) {return; // 已經處理過}const dataSrc = img.getAttribute('data-lazy');if (dataSrc) {const proxy = new ImageProxy(dataSrc, img);this.imageProxies.set(img, proxy);}}/*** 手動觸發圖片加載*/public loadImage(img: HTMLImageElement): void {const proxy = this.imageProxies.get(img);if (proxy) {proxy.load();}}/*** 清理所有資源*/public destroy(): void {this.imageProxies.forEach(proxy => proxy.destroy());this.imageProxies.clear();this.mutationObserver.disconnect();}
}/*** 使用示例*/
class LazyImageExample {private manager: LazyImageManager;constructor() {this.manager = new LazyImageManager();this.setupEventListeners();}/*** 設置事件監聽器*/private setupEventListeners(): void {// 頁面加載完成后初始化if (document.readyState === 'loading') {document.addEventListener('DOMContentLoaded', () => {console.log('Lazy image manager initialized');});}// 頁面卸載時清理資源window.addEventListener('beforeunload', () => {this.manager.destroy();});}
}// 自動初始化
const lazyImageExample = new LazyImageExample();

圖片懶加載時序圖

圖3:圖片懶加載時序圖

CSS樣式支持

/* 懶加載圖片的樣式 */
.lazy-image {transition: opacity 0.3s ease-in-out;background-color: #f0f0f0;
}.lazy-image.loading {opacity: 0.6;background-image: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);background-size: 200px 100%;background-repeat: no-repeat;animation: loading-shimmer 1.5s infinite;
}.lazy-image.loaded {opacity: 1;
}.lazy-image.error {background-color: #ffebee;opacity: 0.8;
}@keyframes loading-shimmer {0% { background-position: -200px 0; }100% { background-position: 200px 0; }
}

代理模式的最佳實踐與對比分析

代理模式 vs 裝飾器模式 vs 適配器模式

設計模式

主要目的

結構特點

使用場景

代理模式

控制訪問,提供代理

代理與目標實現相同接口

RPC調用、懶加載、訪問控制

裝飾器模式

動態添加功能

裝飾器包裝目標對象

功能增強、責任鏈

適配器模式

接口轉換

適配器轉換不兼容接口

系統集成、遺留代碼改造

Spring AOP中的代理應用

/*** Spring AOP代理示例*/
@Component
public class UserService {@Transactional@Cacheable("users")public User getUserById(Long id) {// 業務邏輯return userRepository.findById(id);}@Async@EventListenerpublic void handleUserEvent(UserEvent event) {// 異步事件處理}
}

Spring通過代理模式實現了聲明式事務、緩存、異步執行等功能,開發者只需要添加注解即可享受這些橫切關注點的功能。

性能優化建議

  1. 代理緩存:對于頻繁創建的代理對象,使用緩存機制避免重復創建
  2. 異步處理:在代理中使用異步處理提高響應性能
  3. 資源管理:及時清理不需要的代理對象,避免內存泄漏
  4. 批量操作:對于批量請求,在代理層進行合并處理

結語與展望

通過深入研究代理模式在現代軟件開發中的應用,我深刻認識到這一設計模式的強大之處。在我的實際項目經驗中,代理模式不僅幫助我們解決了技術難題,更重要的是它體現了軟件設計中"開閉原則"和"單一職責原則"的核心思想。

在微服務架構日益普及的今天,RPC代理為我們屏蔽了分布式系統的復雜性,讓開發者能夠專注于業務邏輯的實現。而在前端性能優化領域,圖片懶加載的虛擬代理模式已經成為提升用戶體驗的標準做法。這些實踐讓我深刻理解了代理模式在現代軟件架構中的價值。

展望未來,我認為代理模式將在以下幾個方面發揮更大作用:

首先,在云原生和服務網格(Service Mesh)架構中,代理模式將承擔更多的職責。Envoy、Istio等服務網格產品已經將代理模式推向了基礎設施層面,未來的微服務通信、安全策略、可觀測性都將更多地依賴代理模式的實現。

其次,隨著WebAssembly技術的發展,前端代理的能力將得到顯著提升。我們可以期待更高性能的圖片處理代理、更智能的資源加載策略,以及更豐富的離線功能代理。

最后,在人工智能和機器學習領域,代理模式也將發揮重要作用。模型推理的代理、訓練數據的代理加載、分布式計算的代理協調等場景都為代理模式提供了新的應用空間。

作為技術人員,我們應該持續關注代理模式的演進,深入理解其核心原理,并在實際項目中靈活運用。只有這樣,我們才能在快速變化的技術環境中,構建出既優雅又實用的軟件系統。


參考資源:

  • Spring Cloud OpenFeign官方文檔
  • Apache Dubbo GitHub倉庫
  • gRPC官方文檔
  • Intersection Observer API - MDN
  • HTTP/2協議規范 - RFC 7540

關鍵詞: 代理模式, RPC, 圖片懶加載, Spring Cloud Feign, Intersection Observer, 微服務架構, 性能優化

🌟 嗨,我是IRpickstars!如果你覺得這篇技術分享對你有啟發:

🛠? 點擊【點贊】讓更多開發者看到這篇干貨
🔔 【關注】解鎖更多架構設計&性能優化秘籍
💡 【評論】留下你的技術見解或實戰困惑

作為常年奮戰在一線的技術博主,我特別期待與你進行深度技術對話。每一個問題都是新的思考維度,每一次討論都能碰撞出創新的火花。

🌟 點擊這里👉 IRpickstars的主頁 ,獲取最新技術解析與實戰干貨!

?? 我的更新節奏:

  • 每周三晚8點:深度技術長文
  • 每周日早10點:高效開發技巧
  • 突發技術熱點:48小時內專題解析

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

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

相關文章

登山第二十六梯:單目3D檢測一切——一只眼看世界

文章目錄 一 摘要 二 資源 三 內容 一 摘要 盡管深度學習在近距離 3D 對象檢測方面取得了成功&#xff0c;但現有方法難以實現對新對象和相機配置的零鏡頭泛化。我們介紹了 DetAny3D&#xff0c;這是一種可提示的 3D 檢測基礎模型&#xff0c;能夠在任意相機配置下僅使用單目…

ROS2簡記一:第一個ros2程序,海龜模擬與C++和python的《你好,世界!》

目錄 引言 一、控制小海龜 二、鍵盤控制海龜 三、控制海龜案例的簡單分析 四、ROS2之linux基礎 4.1 linux終端命令 4.1.1 查看當前終端所在目錄 pwd 4.1.2 切換終端所在目錄 cd 4.1.3 查看當前目錄下的文件 ls 4.1.4 主目錄 ~ 4.1.5 文件的操作 4.1.6 命令使用幫助…

監控的基本理論和prometheus安裝

監控的基本理論和prometheus安裝 前言 這篇博客主要講的是關于理論的知識&#xff0c;大家盡可能的消化和吸收&#xff0c;也能擴展大家的知識面 監控的基本概念 監控俗稱為運維的第三只眼。沒有了監控&#xff0c;業務運維都是“瞎子”。所以說監控室運維這個職業的根本&…

互聯網生態下贏家群體的崛起與“開源AI智能名片鏈動2+1模式S2B2C商城小程序“的賦能效應

摘要&#xff1a;本文聚焦未來互聯網贏家群體的構成特征&#xff0c;剖析網紅經濟與專業主播的差異化發展路徑&#xff0c;結合開源AI智能名片鏈動21模式與S2B2C商城小程序的融合創新&#xff0c;提出技術賦能下互聯網商業生態的重構路徑。研究表明&#xff0c;開源AI技術通過智…

OneCode 圖表組件核心優勢解析

一、全方位的可視化能力 OneCode 圖表組件提供了15種專業圖表類型&#xff0c;覆蓋從基礎到高級的數據可視化需求&#xff1a; 基礎圖表&#xff1a;柱狀圖、折線圖、餅圖、面積圖等高級圖表&#xff1a;金字塔圖、雷達圖、儀表盤、LED圖表等實時圖表&#xff1a;實時折線圖、實…

【Linux】RHCE中ansible的配置

1.安裝并配置ansible 第一步先安裝ansible所需軟件 #安裝ansible所需軟件 [devopsworkstation ~]$ sudo dnf install ansible ansible-navigator rhel-system-roles -y 第二步登錄鏡像倉庫&#xff0c;在鏡像倉庫下載鏡像容器來運行ansible 由于ansible-navigator 知ansible…

ubuntu server系統 安裝寶塔

更新系統軟件包sudo apt update && sudo apt upgrade -y提示&#xff0c;如果想博主這樣是存綠色liunx系統&#xff0c;要先安裝python3腳本才可以python3 --version有pyhton版本號就是安裝了&#xff0c;沒有的話就要安裝安裝 Pythonsudo apt update sudo apt install…

用C++實現五子棋游戲

#include <iostream> #include <vector> #include <string> #include <iomanip> // 用于控制輸出格式 #include <limits> // 用于numeric_limitsusing namespace std;// 游戲常量定義 const int BOARD_SIZE 15; // 定義棋盤大小為15x15// 棋…

【LeetCode 熱題 100】73. 矩陣置零——(解法一)空間復雜度 O(M + N)

Problem: 73. 矩陣置零 題目&#xff1a;給定一個 m x n 的矩陣&#xff0c;如果一個元素為 0 &#xff0c;則將其所在行和列的所有元素都設為 0 。請使用 原地 算法。 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(M * N)空間復雜度&#xff1a;O(M N)整體思路…

【深度學習新浪潮】國內零樣本抗體設計的科研進展如何?

什么是AI零樣本抗體設計? AI零樣本抗體設計(Zero-shot AI Antibody Design)是指不依賴任何已知抗體序列或結構數據,僅根據靶點抗原信息,通過人工智能直接生成具有高親和力、高特異性的全新抗體序列的技術。其核心在于突破傳統抗體研發的“數據依賴瓶頸”,實現真正的“從…

【論文閱讀】A Diffusion model for POI recommendation

論文出處&#xff1a;ACM Transactions on Information Systems (TOIS) SCI一區 CCF-A期刊 論文地址&#xff1a;[2304.07041] A Diffusion model for POI recommendation 論文代碼&#xff1a;Yifang-Qin/Diff-POI: The official PyTorch implementation of Diff-POI. 目…

Rust實現FasterR-CNN目標檢測全流程

使用 Rust 和 FasterR-CNN 進行目標檢測 FasterR-CNN 是目標檢測領域廣泛使用的深度學習模型。Rust 生態中可以通過 tch-rs(Torch 綁定)調用預訓練的 PyTorch 模型實現。以下為完整實現步驟: 環境準備 安裝 Rust 和必要的依賴: cargo add tch cargo add anyhow # 錯誤…

Github 2025-07-03Go開源項目日報Top10

根據Github Trendings的統計,今日(2025-07-03統計)共有10個項目上榜。根據開發語言中項目的數量,匯總情況如下: 開發語言項目數量Go項目10JavaScript項目2Go編程語言:構建簡單、可靠和高效的軟件 創建周期:3474 天開發語言:Go協議類型:BSD 3-Clause “New” or “Revise…

XML Schema 安裝使用教程

一、XML Schema 簡介 XML Schema&#xff08;XSD&#xff0c;全稱 XML Schema Definition&#xff09;是用于定義 XML 文檔結構、數據類型和數據約束的標準方式。它比 DTD 更加強大&#xff0c;支持數據類型、默認值、命名空間等&#xff0c;是企業級 XML 應用推薦的驗證方式。…

【字節跳動】數據挖掘面試題0008:計算西瓜視頻內容好評率

文章大綱題目描述題目描述 西瓜視頻近期開展了”2020百大人氣創作者”優質內容扶持項目&#xff0c;鼓勵用戶產出優質的視頻內容。 現需要統計2020年11月01日至2020年11月30日期間創作的視頻中&#xff0c; “科技”大類下“數碼測評"子類的視頻好評率&#xff08;好評率好…

Linux 進程控制:全面深入剖析進程創建、終止、替換與等待

文章目錄引言一、進程創建&#xff1a;fork()系統調用的奧秘1.1 fork()的基本原理1.2 代碼示例與解讀1.3 寫時復制&#xff08;COW&#xff09;優化二、進程終止&#xff1a;exit()與_exit()的抉擇2.1 exit()和_exit()的區別2.2 代碼示例與分析三、進程替換&#xff1a;exec()函…

PJSIP 中的 TCP 傳輸配置指南

PJSIP 支持通過 TCP 傳輸 SIP 消息&#xff0c;相比 UDP 提供了更可靠的傳輸機制。以下是關于在 PJSIP 中使用 TCP 的詳細指南。1. 創建 TCP 傳輸基本 TCP 傳輸配置cpjsua_transport_config tcp_cfg; pjsua_transport_config_default(&tcp_cfg); tcp_cfg.port 5060; // SI…

小菜狗的云計算之旅,今天學習MySQL數據庫基礎知識及操作

目錄 一、概述 數據庫概念 數據庫的類型 關系型數據庫模型 關系數據庫相關概念 二、安裝 1、mariadb安裝 2、mysql安裝 3、啟動并開機自啟 4、本地連接&#xff08;本地登錄&#xff09; 三、mysql數據庫配置與命令 yum安裝后生成的目錄 mysql服務器的啟動腳本 數…

為什么是直接在**原型(prototype)上**添加函數

這是一個非常經典、核心的 JavaScript 面向對象編程問題&#xff1a;> 為什么是直接在**原型&#xff08;prototype&#xff09;上**添加函數&#xff0c;而不是在類/構造函數內部直接添加&#xff1f;你提到的代碼中&#xff1a;javascript function TopSearchComponent() …

深入理解 classnames:React 動態類名管理的最佳實踐

在現代前端開發中&#xff0c;我們經常需要根據組件的狀態、屬性或用戶交互來動態切換 CSS 類名。雖然 JavaScript 提供了多種方式來處理字符串拼接&#xff0c;但隨著應用復雜性的增加&#xff0c;傳統的類名管理方式很快就會變得混亂不堪。這時&#xff0c;classnames 庫就像…