對controller層進行深入學習

目錄

  • 1. controller層是干什么的?
    • 1.1 controller原理圖
    • 1.2 controller層為什么要存在?
      • 1.2.1 分離關注點
      • 1.2.2 響應HTTP請求
      • 1.2.3 數據處理與轉換
      • 1.2.4 錯誤處理與狀態管理
      • 1.2.5 流程控制
      • 1.2.6 依賴注入與測試
    • 1.3 controller層的優點
      • 1.3.1 多端支持
      • 1.3.2 安全性保障
      • 1.3.3 性能優化
    • 1.4 All in All
  • 2. 研究Restful風格
    • 2.1 什么是Restful風格?
      • 2.1.1 功能
      • 2.1.2 Restful風格與傳統風格的區別
        • 2.1.2.1 請求方法
        • 2.1.2.2 數據格式
        • 2.1.2.3 狀態碼使用
        • 2.1.2.4 異常處理
        • 2.1.2.5 無狀態性
        • 2.1.2.6 總結
  • 3. controller層代碼
    • 3.1 定義controller風格的注解
      • 3.1.1 @RestController
      • 3.1.2 @RequestMapping
      • 3.1.3 @Slf4j
    • 3.2 依賴注入注解
      • 3.2.1 @Resource和@Autowired的相同點
      • 3.2.2 @Resource和@Autowired的不同點
      • 3.2.3 總結
    • 3.3 依賴注入三種方式
      • 3.3.1 字段注入(最簡單,有風險)
      • 3.3.2 構造器注入(最安全,推薦)
      • 3.3.3 Setter方法注入
  • 4. controller層接口代碼詳解
    • 4.0 HTTP常見請求方法合集
    • 4.1 模糊查詢---接口
    • 4.2 findAll---接口
    • 4.3 根據id查詢---接口
    • 4.4 增加---接口
    • 4.5 刪除---接口
    • 4.5 更新---接口
  • 5 總結

1. controller層是干什么的?

1.1 controller原理圖

在這里插入圖片描述
在Web應用程序中,控制器層(Controller)是模型-視圖-控制器(MVC)架構模式的一個關鍵組成部分。控制器負責接收用戶的輸入調用業務邏輯層來處理這些輸入并返回適當的響應給視圖層
舉個例子吧:

平時登陸賬號的時候,你想要輸入賬號和密碼吧,然后點擊登陸的時候,用戶請求是最先傳到controller層的,然后controller層再傳到service層,為什么不直接傳給service層?例如,密碼長度不符合要求,或者賬號不是有效的電子郵件格式,那么沒有必要將請求轉發到服務層或數據庫層進行更深入的驗證。通過在控制器層進行初步驗證,可以減少不必要的服務層或數據庫層操作,從而提高系統性能和響應速度。另外,在控制器層進行格式驗證可以作為安全措施的一部分,防止惡意或格式錯誤的數據到達后端服務,減少潛在的安全風險。以前的黑客不就玩的sql注入嗎,當時的開發者都沒有意識到在數據庫查詢中直接使用用戶輸入的危險。

1.2 controller層為什么要存在?

在現代Web應用程序中,用戶請求通常不會直接傳遞給服務層(Service),而是通過控制器層(Controller)來處理,這種設計主要是基于以下幾個原因:

1.2.1 分離關注點

控制器層和業務邏輯層分離,使得每一層都只關注自己的職責。控制器層關注如何接收請求、驗證輸入和調用相應的業務邏輯。服務層則關注業務規則和業務流程的具體實現。

1.2.2 響應HTTP請求

在Spring框架中,Controller通過@Controller或@RestController注解標識,配合@RequestMapping等注解,能夠響應不同路徑的HTTP請求。如果沒有Controller,系統將無法正確解析和響應用戶請求,導致功能無法實現。

1.2.3 數據處理與轉換

Controller負責將接收到的數據(如用戶輸入的用戶名和密碼)傳遞給Service層進行驗證,并將驗證結果轉換為適合客戶端展示的格式。例如,使用@ResponseBody注解可以將Java對象自動轉換為JSON格式,方便前端處理。

1.2.4 錯誤處理與狀態管理

Controller還負責處理請求過程中可能出現的錯誤情況,并管理HTTP狀態碼。如果去掉Controller,這些錯誤處理和狀態管理將無處安放,可能導致用戶體驗不佳和安全風險

1.2.5 流程控制

Controller通過方法調用和返回值決定后續執行流程。例如,如果用戶登錄失敗,Controller可以決定重新顯示登錄頁面和錯誤信息;如果登錄成功,則跳轉到用戶的主頁。這種流程控制能力是細粒度處理請求不可或缺的。

1.2.6 依賴注入與測試

Spring框架中的Controller可以利用依賴注入(DI)集成其他組件(如Service、DAO等),并通過@Autowired注解自動裝配所需的依賴。這使得單元測試變得更加容易,同時也降低了組件間的耦合度。

1.3 controller層的優點

1.3.1 多端支持

在一個多端應用(如網頁、移動端)中,不同的前端可能發送類似的請求(如獲取用戶信息)。Controller可以統一處理這些請求,減少重復代碼。

1.3.2 安全性保障

Controller可以結合Spring Security等安全框架,提供認證、授權和跨站請求偽造(CSRF)防護等功能,增強應用的安全性。

1.3.3 性能優化

通過合理的Controller設計(如緩存、異步處理),可以提升系統的響應速度和并發處理能力。

1.4 All in All

Controller在Web應用中扮演著核心角色,負責處理請求、響應、數據轉換、錯誤處理和流程控制等關鍵任務。去掉Controller將導致系統無法正常響應用戶請求,破壞架構的模塊化和可維護性。因此,在實際開發中應充分重視Controller的設計和實現。

以下是控制器層的詳細闡述:

2. 研究Restful風格

2.1 什么是Restful風格?

Restful就是一個資源定位及資源操作的風格。不是標準也不是協議,只是一種風格。基于這個風格設計的軟件可以更簡潔,更有層次,更易于實現緩存等機制。

2.1.1 功能

  1. 資源:互聯網所有的事物都可以被抽象為資源
  2. 資源操作:使用POST、DELETE、PUT、GET,使用不同方法對資源進行操作。
  3. 分別對應 添加、 刪除、修改、查詢。

2.1.2 Restful風格與傳統風格的區別

2.1.2.1 請求方法

Restful風格:Restful風格的Controller全面使用HTTP的方法,包括GET、POST、PUT、DELETE等。每種方法都有具體的含義,例如GET用于獲取資源,POST用于創建新資源,PUT用于更新資源,DELETE用于刪除資源。
傳統風格:傳統風格的Controller通常只使用GET和POST請求方法。這意味著不管需要進行什么樣的操作,基本都依賴于這兩種方法,可能導致一個操作對應多個URL。

2.1.2.2 數據格式

Restful風格:Restful風格的接口通常使用JSON或XML作為數據交換格式,它們易于解析和生成,同時具有良好的可讀性。
傳統風格:通常使用xml。

2.1.2.3 狀態碼使用

Restful風格:Restful風格的Controller充分利用了HTTP狀態碼來表示不同的結果狀態,如200(成功)、201(已創建)、404(未找到)、500(服務器錯誤)等,這些狀態碼能明確告訴客戶端請求的處理結果。
傳統風格:傳統風格的Controller中,狀態碼的使用較為單一,通常只有200(成功)被頻繁使用,其他狀態碼較少出現。

2.1.2.4 異常處理

Restful風格:Restful風格的Controller采用統一的異常處理器,可以集中管理錯誤處理邏輯,并返回統一的錯誤信息和狀態碼。
傳統風格:傳統風格的異常處理可能分散在不同的Controller中,導致代碼重復和管理不便。

2.1.2.5 無狀態性

Restful風格:Restful風格的設計是無狀態的,每次請求都包含了所有必需的信息,這使得系統更加簡單且易于擴展。
傳統風格:傳統風格的Controller可能會依賴存儲在服務器端的會話(Session)狀態,這導致系統在水平擴展時面臨挑戰。

2.1.2.6 總結

Restful風格的Controller在URL設計、HTTP方法使用、狀態碼管理等方面具有明顯優勢,使得后端服務更加標準化和易于維護。在實際開發中,應當盡量采用Restful風格的設計原則來構建Web應用的后端服務。

3. controller層代碼

package com.goblin.BIbackend.controller;import com.goblin.BIbackend.common.BaseResponse;
import com.goblin.BIbackend.common.ListWithTotal;
import com.goblin.BIbackend.common.ResultUtils;
import com.goblin.BIbackend.model.entity.Complaints;
import com.goblin.BIbackend.service.ComplaintsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.List;@RestController
@RequestMapping("/complaints")
@Slf4j
public class ComplaintsController {@Resourceprivate ComplaintsService complaintsService;//模糊查詢@PostMapping("/search")public BaseResponse<ListWithTotal<Complaints>> search(@RequestBody Complaints keyword) {log.info("查詢投訴信箱:{}", keyword);List<Complaints> complaints = complaintsService.search1(keyword);int total = complaints.size();log.info("查詢投訴信箱總數:{}", total);ListWithTotal<Complaints> list = new ListWithTotal<>(complaints, total);return ResultUtils.success(list);}@GetMapping("/list")public BaseResponse<ListWithTotal<Complaints>> list() {List<Complaints> complaints = complaintsService.getList();int total = complaintsService.count1();log.info("查詢投訴信箱總數:{}", total);ListWithTotal<Complaints> list = new ListWithTotal<>(complaints, total);return ResultUtils.success(list);}@GetMapping("/select2")public BaseResponse<Complaints> select2(Long id) {log.info("查詢投訴信息:{}", id);Complaints complaints = complaintsService.select2(id);log.info("查詢投訴信息:{}", complaints);return ResultUtils.success(complaints);}@PostMapping("/insert2")public BaseResponse<Complaints> insert2(@RequestBody Complaints complaints) {Complaints result = complaintsService.insert2(complaints);return ResultUtils.success(result);}@DeleteMapping("/delete2")public BaseResponse<Long> delete2(Long id) {complaintsService.delete2(id);return ResultUtils.success(id);}@PutMapping("/update2")public BaseResponse<Complaints> update2(@RequestBody Complaints complaints) {complaintsService.update2(complaints);return ResultUtils.success(complaints);}}

這段代碼是一個Spring Boot應用程序中的ComplaintsController類,它使用Spring MVC框架來處理(Complaints)相關的HTTP請求。以下是對代碼的逐行解析:

3.1 定義controller風格的注解

@RestController
@RequestMapping("/complaints")
@Slf4j

這段代碼的主要作用是定義一個處理與"/complaints"相關的HTTP請求的控制器,并自動生成日志對象。

3.1.1 @RestController

這是Spring 4之后新加入的注解,原來在@Controller中返回json需要@ResponseBody來配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默認返回json格式。這個注解標識這個類是一個RestController,即控制器(Controller),主要用來處理由DispatcherServlet分發的請求,還可以對數據進行校驗等操作。

DispatcherServlet是Spring MVC框架中的一個核心組件,它作為前端控制器(Front Controller),負責將接收到的HTTP請求轉發到相應的處理器(Controller)。DispatcherServlet是Spring MVC中的中央調度器,它擴展了Servlet API,提供了一種機制來映射請求URL到對應的處理器方法。

3.1.2 @RequestMapping

這個注解用于映射Web請求,即訪問"/complaints"路徑時,會執行該類下的某個方法。它可以應用于類或方法上,當應用于類上時,表示類中的所有響應請求的方法都是以該地址作為父路徑。

3.1.3 @Slf4j

這是Lombok庫中的一個注解,用于自動生成日志對象。在使用時,只需在類上添加此注解,就可以自動生成名為log的SLF4J、Log4j、java.util.logging、Commons Logging、Logback以及java.lang.Appendable的實例。

3.2 依賴注入注解

    @Resourceprivate ComplaintsService complaintsService;

先說說@Resource和@Autowired。@Resource和@Autowired都是Spring框架提供的依賴注入(DI)注解,用于實現自動裝配bean。

3.2.1 @Resource和@Autowired的相同點

1.依賴注入:兩者都用于將Spring容器中的bean自動注入到字段、構造函數或setter方法中。
2.減少代碼:通過使用這兩個注解,可以減少樣板代碼,即不需要手動編寫代碼來從容器中獲取bean。
3.支持類型注入:它們都支持通過類型來自動裝配,意味著Spring會查找容器中相應類型的bean來注入。

3.2.2 @Resource和@Autowired的不同點

1.來源:@Autowired是Spring自己的注解,屬于org.springframework.beans.factory.annotation包。
@Resource是Java EE的注解,適用于更廣泛的Java應用,不僅限于Spring框架。
2.注入方式:@Autowired:默認按類型(byType)注入,需要時可以結合@Qualifier指定具體的bean名稱。
@Resource:默認按名稱(byName)注入,也可通過配置type屬性改為按類型注入。
3.參數配置:@Autowired:只有一個required參數,表示是否需要這個依賴。
@Resource:包含多個參數,最重要的是name和type,靈活性更高。
4.使用場景:@Autowired更常用于Spring應用程序中,特別是在使用Spring框架的注解配置時。
@Resource可以用于那些需要兼容Java EE注解的場合,或者在某些特定情況下,開發者可能更傾向于使用Java EE的注解風格。
5.應用建議:@Autowired:更適合Spring環境,特別是當需要更靈活的依賴注入時(例如構造器注入)。
@Resource:更適合與Spring解耦的情境,或者在EE環境中使用。
在Spring配置中,如果同時使用了@Autowired和@Resource,Spring會首先尊重@Autowired的配置。
7.異常處理:@Autowired在找不到bean時會拋出NoSuchBeanDefinitionException。
@Resource在找不到bean時可能會拋出ResourceException。

3.2.3 總結

@Autowired和@Resource都可以用來實現依賴注入,但它們在自動裝配的默認行為、來源、使用場景和異常處理等方面存在差異。在Spring應用程序中,推薦使用@Autowired,因為它提供了更好的Spring集成和更靈活的配置選項。

3.3 依賴注入三種方式

依賴注入是一種設計模式,用來實現對象之間的依賴關系。傳統的面向對象編程中,類與類之間的依賴關系是通過硬編碼來實現的,而依賴注入則將這種依賴關系交給外部容器來處理,從而實現了解耦。
在Spring中依賴注入有三大類:字段注入、構造器注入、Setter方法注入。

3.3.1 字段注入(最簡單,有風險)

字段注入是通過在類的字段上使用注解來直接注入依賴對象的一種方式,雖然簡單直接,但并不推薦使用,因為它破壞了類的封裝性。
字段注入會引起以下的問題

  1. 對象的外部可見性
  2. 可能導致循環依賴
  3. 無法設置注入的對象為final,也無法注入靜態變量

什么是字段注入?舉例如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class MyClass {// 使用@Autowired注解進行字段注入@Autowiredprivate MyService myService;public void doSomething() {myService.performAction();}
}

字段注入非常的簡便,通過以上代碼我們可以輕松的使用MyService類。

MyService myService= new MyService();
myService.performAction();

這樣執行結果為空指針異常,這就是字段注入的第一個問題:對象的外部可見性

public class TestA(){@Autowiredprivate TestB testB;}
public class TestB(){@Autowiredprivate TestA testA;}

上面兩段代碼卡bug,這段代碼在idea中不會報任何錯誤,但是啟動項目時會發現報錯,大致意思是:創建Bean失敗,原因是當前Bean已經作為循環引用的一部分注入到了其他Bean中。
這就是字段注入的第二個問題:可能導致循環依賴
字段注入還有第三個問題:無法設置注入的對象為final,也無法注入靜態變量,原因是變量必須在類實例化進行初始化。

3.3.2 構造器注入(最安全,推薦)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class MyClass {private final MyService myService;// 使用@Autowired注解進行構造器注入@Autowiredpublic MyClass(MyService myService) {this.myService = myService;}public void doSomething() {myService.performAction();}
}

在這個例子中,MyClass的構造函數接收一個MyService類型的參數,并通過@Autowired注解告訴Spring框架自動注入一個合適的MyService實例。這樣,當創建MyClass的實例時,Spring會自動調用帶有@Autowired注解的構造函數,并將相應的依賴項傳遞給它。

構造器注入通過在類的構造函數上使用注解來自動裝配依賴對象。與字段注入相比,構造器注入有以下優點:
1.強制依賴關系:構造器注入要求必須提供所有必需的依賴項,否則將無法創建類的實例。這有助于確保類在使用之前已經正確地初始化了其依賴項。
2.不可變性:由于構造器注入是在構造函數中完成的,一旦對象被創建,其依賴項就無法更改。這有助于保持對象的不變性,并減少潛在的錯誤和副作用。
3.可測試性:構造器注入使得單元測試更加容易,因為可以在測試時輕松地提供模擬或存根依賴項。

3.3.3 Setter方法注入

Setter方法注入是依賴注入的一種方式,它**通過在目標類中定義一個或多個setter方法來接收依賴項的實例。**這種方式允許將依賴項的創建和管理從使用對象的類中分離出來,從而實現解耦和易于維護的代碼。

public class MyClass {private MyDependency myDependency;// Setter method for dependency injectionpublic void setMyDependency(MyDependency myDependency) {this.myDependency = myDependency;}public void doSomething() {// Use the injected dependencymyDependency.performAction();}
}

在這個例子中,MyClass 有一個 myDependency 屬性,它需要被注入一個 MyDependency類型的實例。通過定義一個名為 setMyDependency的setter方法,我們可以在外部容器(如Spring)中配置并注入所需的依賴項。
當Spring容器啟動時,它會掃描所有的bean定義,并根據配置文件或其他配置信息自動調用相應的setter方法,將依賴項注入到目標對象中。這樣,我們就可以在不修改目標類的代碼的情況下,靈活地更改依賴項的實現或配置。
需要注意的是,盡管setter方法注入是一種常見的依賴注入方式,但它并不是唯一的選擇。其他依賴注入方式,如構造器注入、字段注入和接口注入等,也可以用來滿足不同的需求和場景。

4. controller層接口代碼詳解

4.0 HTTP常見請求方法合集

在RESTful API設計中,通常使用GET、POST、PUT、PATCH和DELETE方法來操作資源。這些方法的選擇反映了操作的語義,有助于保持API的直觀性和一致性。例如,使用GET來請求數據,使用POST來創建新資源,使用PUT來更新現有資源,使用DELETE來刪除資源。

  1. GET:請求獲取指定的資源。
  2. POST:向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
  3. PUT:從客戶端向服務器傳送的數據取代指定的文檔的內容。
  4. DELETE:請求服務器刪除指定的內容。
  5. PATCH:對資源進行部分修改。

4.1 模糊查詢—接口

@PostMapping("/search")public BaseResponse<ListWithTotal<Complaints>> search(@RequestBody Complaints keyword) {log.info("查詢投訴信箱:{}", keyword);List<Complaints> complaints = complaintsService.search1(keyword);int total = complaints.size();log.info("查詢投訴信箱總數:{}", total);ListWithTotal<Complaints> list = new ListWithTotal<>(complaints, total);return ResultUtils.success(list);}

模糊查詢:客戶端返回一個Complaints 類對象到controller層,用POST接口。

在Spring框架中,@PostMapping(“/search”)是一個注解,用于將HTTP的POST請求映射到特定的處理方法。這里的"/search"是URL路徑的一部分,表示當客戶端向服務器發送一個POST請求到"/search"路徑時,該請求將被路由到帶有@PostMapping(“/search”)注解的方法進行處理。
具體來說,@PostMapping(“/search”)中的"search"是一個字符串字面量,它定義了處理POST請求的URL路徑。在這個例子中,當客戶端發送一個POST請求到"/search"路徑時,服務器會調用帶有@PostMapping(“/search”)注解的方法來處理這個請求。這個方法可以接收和處理來自客戶端的數據,并返回相應的響應。

BaseResponse是一個通用的響應類,用于封裝API接口的返回結果。它包含一些常見的屬性,如code、message和data。BaseResponse表示返回的數據類型是一個包含投訴的列表和總數的對象。

@RequestBody Complaints keyword是一個Spring框架中的注解,用于將HTTP請求體中的數據綁定到方法參數上。在上面的代碼中,Complaints是一個Java類,表示投訴信息的數據結構。keyword 是這個類的一個實例,用于接收客戶端發送的投訴信息。
當客戶端發送一個POST請求到服務器的"/search"路徑時,請求體中的數據會被解析并轉換為Complaints類的實例。然后,這個實例會被傳遞給search方法作為參數keyword。

ResultUtils.success(list) 是一個方法調用,它是一個工具類中的一個靜態方法。這個方法的作用是創建一個成功的響應對象,并將傳入的參數 list 作為數據返回給客戶端。
在上面的代碼中,list 是一個包含投訴信息的列表,而 ResultUtils.success(list) 方法會創建一個BaseResponse 類型的對象,并設置狀態碼為成功(例如200),同時將 list作為響應的數據部分。這樣,當客戶端接收到這個響應時,它將能夠獲取到包含投訴信息的數據。
ResultUtils.success()`方法封裝一些常見的響應結構,如狀態碼、消息和數據等,以便在應用程序中統一處理響應結果。

在這里插入圖片描述

4.2 findAll—接口

@GetMapping("/list")public BaseResponse<ListWithTotal<Complaints>> list() {List<Complaints> complaints = complaintsService.getList();int total = complaintsService.count1();log.info("查詢投訴信箱總數:{}", total);ListWithTotal<Complaints> list = new ListWithTotal<>(complaints, total);return ResultUtils.success(list);}

findAll:請求獲取所有的Complaints對象,用GET接口。

4.3 根據id查詢—接口

@GetMapping("/select2")public BaseResponse<Complaints> select2(Long id) {log.info("查詢投訴信息:{}", id);Complaints complaints = complaintsService.select2(id);log.info("查詢投訴信息:{}", complaints);return ResultUtils.success(complaints);}

4.4 增加—接口

@PostMapping("/insert2")public BaseResponse<Complaints> insert2(@RequestBody Complaints complaints) {Complaints result = complaintsService.insert2(complaints);return ResultUtils.success(result);}

增加:將一個Complaints 對象傳到controller層,用POST接口。

4.5 刪除—接口

@DeleteMapping("/delete2")public BaseResponse<Long> delete2(Long id) {complaintsService.delete2(id);return ResultUtils.success(id);}

刪除:傳id給controller層,請求刪除指定的Complaints對象,用DELETE接口。

4.5 更新—接口

@PutMapping("/update2")public BaseResponse<Complaints> update2(@RequestBody Complaints complaints) {complaintsService.update2(complaints);return ResultUtils.success(complaints);}

更新:將一個Complaints 對象傳到controller層取代原有Complaints ,從客戶端向服務器傳送的數據取代指定的文檔的內容,用PUT接口。

5 總結

文章首先講了controller層的重要性和優點,然后講了restful風格和傳統風格,接著對代碼進行分析:分析了依賴注入的三種方法,最后是對接口的解析,不可謂不深刻。看完這篇文章應該能知道什么是controller層。代碼誰都會寫,真正的區別在于對代碼底層的理解。

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

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

相關文章

Gin框架自定義路由

Gin框架是一個用Go語言&#xff08;Golang&#xff09;編寫的Web框架&#xff0c;它提供了靈活且高效的路由系統。在Gin框架中&#xff0c;自定義路由是一個基礎且重要的操作&#xff0c;它允許開發者定義應用程序如何處理不同的HTTP請求。以下是自定義路由的詳細步驟和方法&am…

Linux虛擬化大師:使用 KVM 和 QEMU 進行高級虛擬化管理

Linux 虛擬化大師&#xff1a;使用 KVM 和 QEMU 進行高級虛擬化管理 虛擬化技術是現代數據中心的核心技術之一&#xff0c;它可以將一臺物理服務器分割成多個虛擬機&#xff0c;從而提高資源利用率&#xff0c;降低成本&#xff0c;并增強系統的靈活性和可擴展性。KVM&#xf…

C++ | Leetcode C++題解之第225題用隊列實現棧

題目&#xff1a; 題解&#xff1a; class MyStack { public:queue<int> q;/** Initialize your data structure here. */MyStack() {}/** Push element x onto stack. */void push(int x) {int n q.size();q.push(x);for (int i 0; i < n; i) {q.push(q.front());…

C++ 【 Open3D 】 點云按高程進行賦色

一、 Open3D中根據點云的高程度信息為點云中的每個點附上顏色&#xff0c;并保存顏色渲染結果&#xff01; #include<iostream> #include<open3d/Open3D.h>using namespace std;int main() {//-------------------------------讀取點云--------------------------…

nasa數據集——1 度網格單元的全球月度土壤濕度統計數據

AMSR-E/Aqua level 3 global monthly Surface Soil Moisture Averages V005 (AMSRE_AVRMO) at GES DISC GES DISC 的 AMSR-E/Aqua 第 3 級全球地表土壤水分月平均值 V005 (AMSRE_AVRMO) AMSR-E/Aqua level 3 global monthly Surface Soil Moisture Standard Deviation V005 (…

優化 .NET Core 應用程序的安全性和性能以應對高負載

一. .NET Core 中的安全措施 1. 身份驗證和授權 實施強大的身份驗證和授權機制是保護應用程序資源的基礎。.NET Core 內置支持各種身份驗證方案&#xff0c;例如 JWT&#xff08;JSON Web 令牌&#xff09;、OAuth 和 OpenID Connect。通過配置身份驗證中間件并定義授權策略&…

vue中el-table單元格復制功能

一、單頁面中使用 1.在el-table上綁定單擊事件 cell-click“copyText” 或雙擊事件 cell-dblclick“copyText” 注&#xff1a;cell-dblclick函數有四個參數&#xff0c;分別是row, column, cell, event&#xff1b; row&#xff1a;可看到被其操作單元格所在行的所有的數據&…

【IT領域新生必看】解鎖 `final` 關鍵字的秘密:Java 編程中的終極武器

文章目錄 引言什么是 final 關鍵字&#xff1f;一、 final 變量final 局部變量final 實例變量final 靜態變量 二、 final 方法三、 final 類四、 final 關鍵字的實際應用1. 定義常量2. 防止方法被重寫3. 創建不可變類4. 優化性能 五、 final 的一些常見誤區1. final 變量不能在…

力扣995.K連續位的最小翻轉次數

力扣995.K連續位的最小翻轉次數 因為翻轉順序改變不影響最終結果 因此從頭找每個位置翻轉后的結果如果為0 將從它開始的K長的數組翻轉 class Solution {public:int minKBitFlips(vector<int>& nums, int k) {int n nums.size();vector<int> s(n1);int res0…

05.FFMPEG日志系統

一、頭文件 #include <libavutil/log.h> 二、常用函數 1、av_log_set_level void av_log_set_level(int level);該函數用于設置全局日志級別。 2、av_log void av_log(void* avcl, int level, const char* fmt, ...);該函數用于輸出日志消息。avcl 參數是相關聯的上下…

uboot學習:(三)目錄分析

目錄 目錄分析 uboot自帶 編譯生成的文件 分析之前需要編譯一次uboot源碼&#xff0c;編譯之后的uboot源碼會多出來很多文件 目錄分析 uboot自帶 api 與硬件無關的API函數arch 與架構體系有關的代碼 里面有x86,arm等架構文件夾 架構文件夾里面有cpu&#xff0c;設備樹等…

使用 Nuxt 3 搭建國際官網

搭建國際官網是一個復雜的任務,涉及多方面的技術和策略。在這篇文章中,我們將探討如何使用 Nuxt 3 框架搭建一個國際化官網,并展示其在 SEO 優勢和全棧可維護性方面的卓越性能。 使用 Nuxt 3 搭建國際官網 1. Nuxt 3 簡介 Nuxt 3 是一個基于 Vue 3 和 Vite 的框架,旨在構…

大數據面試題之ElasticSearch(2)

目錄 ElasticSearch的單播、多播和廣播 什么是Zen Discovery機制 ElasticSearch和Solr主要區別 ElasticSearch和Solr各自適用于哪些場景 Elasticsearch的同類產品有哪些 Elasticsearch有哪些主要應用場景 Elasticsearch 中執行搜索的各種可能方式有哪些 Elasticsearch 中…

UWB系列教程(一)UWB簡介

UWB系列教程&#xff08;一&#xff09;&#xff1a;UWB簡介 超寬帶&#xff08;Ultra-Wideband, UWB&#xff09;技術作為一種先進的無線通信技術&#xff0c;近年來在多個領域展現出了巨大的潛力和應用前景。 什么是超寬帶&#xff08;UWB&#xff09;技術&#xff1f; 超…

Java中的數據緩存技術及其應用

Java中的數據緩存技術及其應用 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在現代應用程序中&#xff0c;數據緩存是一種重要的技術手段&#xff0c;用于提…

linux中的僵尸進程

僵尸進程&#xff08;Zombie Process&#xff09;是指在操作系統中&#xff0c;一個進程已經終止執行了&#xff08;即已經退出&#xff09;&#xff0c;但是其父進程還沒有通過 wait() 系統調用來獲取該進程的終止狀態&#xff08;exit status&#xff09;&#xff0c;因此該進…

Python面試寶典第10題:精選選擇題

題目1 在以下函數中&#xff0c;b和a的關系是___。 def add_one_to_list(lst):lst.append(1)return lsta [1, 2, 3] b add_one_to_list(a) A. b是a的淺拷貝 B. b和a是同一個列表對象 C. b是a的深拷貝 D. b是a的一個子列表 題目2 以下函數的作用是___。 def operate_s…

C++多態的實現原理

靜態多態&#xff08;編譯期&#xff09; 函數重載&#xff1a; 允許在同一個作用域中聲明多個功能類似的同名函數函數的參數列表不同&#xff08;參數個數&#xff0c;參數類型&#xff0c;參數順序&#xff09;注意&#xff1a;不能通過函數返回值區分&#xff08;name man…

(補充)IDEA項目結構

文章目錄 前言一、pycharm中Python項目結構二、IDEA中的java項目結構設計總結前言 本文主要介紹一下pycharm和IDEA里面的項目結構的使用方法 一、pycharm中Python項目結構 之前我們在pycharm做過python項目,項目結構很清晰,還是比較靈活的。 一般項目里面就是 數據驅動、數…

【JavaSE】程序邏輯控制

目錄 1. 順序結構 2. 分支結構 2.1 if語句 2.1.1 語法格式1 2.1.2 語法格式2 2.1.3 語法格式3 2.1.4 練習 2.1.5 注意事項 2.2 switch 語句 3. 循環結構 3.1 while循環 3.1.1 語法格式 3.1.2 代碼示例 3.1.3 注意事項 3.2 break 3.3 continue 3.4 for循環 …