【Java Web】3.SpringBootWeb請求響應

📘博客主頁:程序員葵安

🫶感謝大家點贊👍🏻收藏?評論?🏻

????????????????文章目錄

一、請求

1.1 postman

1.2 簡單參數?

1.3 實體參數

1.4 數組集合參數

1.5 日期參數

1.6 JSON參數?

1.7 路徑參數

二、響應

2.1 @ResponseBody

2.2 統一響應結果

三、分層解耦

3.1 三層架構

3.2 分層解耦

3.3 IOC&DI


一、請求

接收頁面傳遞過來的請求數據

1.1 postman

  • Postman是一款功能強大的網頁調試與發送網頁HTTP請求的Chrome插件。

    Postman原是Chrome瀏覽器的插件,可以模擬瀏覽器向后端服務器發起任何形式(如:get、post)的HTTP請求

    使用Postman還可以在發起請求時,攜帶一些請求參數、請求頭等信息

  • 作用:常用于進行接口測試

  • 特征

    • 簡單

    • 實用

    • 美觀

    • 大方

postman使用

創建工作空間:

創建請求: ?

?點擊"Save",保存當前請求

1.2 簡單參數?

簡單參數:在向服務器發起請求時,向服務器傳遞的是一些普通的請求數據。

SpringBoot方式?

?在Springboot的環境中,對原始的API進行了封裝,接收參數的形式更加簡單。 如果是簡單參數,參數名與形參變量名相同,定義同名的形參即可接收參數。

@RestController
public class RequestController {// http://localhost:8080/simpleParam?name=Tom&age=10// 第1個請求參數: name=Tom   參數名:name,參數值:Tom// 第2個請求參數: age=10     參數名:age , 參數值:10//springboot方式@RequestMapping("/simpleParam")public String simpleParam(String name , Integer age ){//形參名和請求參數名保持一致System.out.println(name+"  :  "+age);return "OK";}
}

postman測試( GET 請求):

?postman測試( POST請求 ):

結論:不論是GET請求還是POST請求,對于簡單參數來講,只要保證==請求參數名和Controller方法中的形參名保持一致==,就可以獲取到請求參數中的數據值。

請求參數名和形參名不同時:沒報錯,但無法接收到請求數據。

可使用Spring提供的@RequestParam注解完成映射

@RestController
public class RequestController {// http://localhost:8080/simpleParam?name=Tom&age=20// 請求參數名:name//springboot方式@RequestMapping("/simpleParam")public String simpleParam(@RequestParam("name") String username , Integer age ){System.out.println(username+"  :  "+age);return "OK";}
}

注意:@RequestParam中的required屬性默認為true(默認值也是true),代表該請求參數必須傳遞,如果不傳遞將報錯,可改為false,表示參數可選

1.3 實體參數

在使用簡單參數做為數據傳遞方式時,前端傳遞了多少個請求參數,后端controller方法中的形參就要書寫多少個。如果請求參數比較多,通過上述的方式一個參數一個參數的接收,會比較繁瑣。

此時,我們可以考慮將請求參數封裝到一個實體類對象中。 要想完成數據封裝,需要遵守如下規則:請求參數名與實體類的屬性名相同

簡單實體參數:

定義POJO實體類:

public class User {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}

Controller方法:

@RestController
public class RequestController {//實體參數:簡單實體對象@RequestMapping("/simplePojo")public String simplePojo(User user){System.out.println(user);return "OK";}
}

復雜實體對象:

復雜實體對象指的是,在實體類中有一個或多個屬性,也是實體對象類型的。如下:

  • User類中有一個Address類型的屬性(Address是一個實體類)

復雜實體對象的封裝,需要遵守如下規則:

  • 請求參數名與形參對象屬性名相同,按照對象層次結構關系即可接收嵌套實體類屬性參數。

定義POJO實體類:

  • Address實體類

public class Address {private String province;private String city;public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}@Overridepublic String toString() {return "Address{" +"province='" + province + '\'' +", city='" + city + '\'' +'}';}
}
  • User實體類
public class User {private String name;private Integer age;private Address address; //地址對象public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +", address=" + address +'}';}
}

Controller方法:

@RestController
public class RequestController {//實體參數:復雜實體對象@RequestMapping("/complexPojo")public String complexPojo(User user){System.out.println(user);return "OK";}
}

1.4 數組集合參數

數組集合參數的使用場景:在HTML的表單中,有一個表單項是支持多選的(復選框),可以提交選擇的多個值。

后端程序接收多個值的方式有兩種:

  1. 數組

  2. 集合

數組

數組參數:請求參數名與形參數組名稱相同且請求參數為多個,定義數組類型形參即可接收參數

?Controller方法:

@RestController
public class RequestController {//數組集合參數@RequestMapping("/arrayParam")public String arrayParam(String[] hobby){System.out.println(Arrays.toString(hobby));return "OK";}
}

Postman測試:

在前端請求時,有兩種傳遞形式:

方式一: xxxxxxxxxx?hobby=game&hobby=java

方式二:xxxxxxxxxxxxx?hobby=game,java

集合

集合參數:請求參數名與形參集合對象名相同且請求參數為多個,@RequestParam 綁定參數關系

默認情況下,請求中參數名相同的多個值,是封裝到數組。如果要封裝到集合,要使用@RequestParam綁定參數關系

?Controller方法:

@RestController
public class RequestController {//數組集合參數@RequestMapping("/listParam")public String listParam(@RequestParam List<String> hobby){System.out.println(hobby);return "OK";}
}

Postman測試:

方式一: xxxxxxxxxx?hobby=game&hobby=java

方式二:xxxxxxxxxxxxx?hobby=game,java

1.5 日期參數

在一些特殊的需求中,可能會涉及到日期類型數據的封裝。

為日期的格式多種多樣(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那么對于日期類型的參數在進行封裝的時候,需要通過@DateTimeFormat注解,以及其pattern屬性來設置日期的格式。

  • @DateTimeFormat注解的pattern屬性中指定了哪種日期格式,前端的日期參數就必須按照指定的格式傳遞。

  • 后端controller方法中,需要使用Date類型或LocalDateTime類型,來封裝傳遞的參數。

Controller方法:

@RestController
public class RequestController {//日期時間參數@RequestMapping("/dateParam")public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){System.out.println(updateTime);return "OK";}
}

1.6 JSON參數?

JSON是開發中最常用的前后端數據交互方式

我們學習JSON格式參數,主要從以下兩個方面著手:

  1. Postman在發送請求時,如何傳遞json格式的請求參數

  2. 在服務端的controller方法中,如何接收json格式的請求參數

Postman發送JSON格式數據:

服務端Controller方法接收JSON格式數據:

  • 傳遞json格式的參數,在Controller中會使用實體類進行封裝。

  • 封裝規則:JSON數據鍵名與形參對象屬性名相同,定義POJO類型形參即可接收參數。需要使用 @RequestBody標識。

  • @RequestBody注解:將JSON數據映射到形參的實體類對象中(JSON中的key和實體類中的屬性名保持一致)

實體類:Address

public class Address {private String province;private String city;//省略GET , SET 方法
}

實體類:User

public class User {private String name;private Integer age;private Address address;//省略GET , SET 方法
}    

Controller方法:

@RestController
public class RequestController {//JSON參數@RequestMapping("/jsonParam")public String jsonParam(@RequestBody User user){System.out.println(user);return "OK";}
}

1.7 路徑參數

在現在的開發中,經常還會直接在請求的URL中傳遞參數。

路徑參數:

  • 前端:通過請求URL直接傳遞參數

  • 后端:使用{…}來標識該路徑參數,需要使用@PathVariable獲取路徑參數

?Controller方法:

@RestController
public class RequestController {//路徑參數@RequestMapping("/path/{id}")public String pathParam(@PathVariable Integer id){System.out.println(id);return "OK";}
}

傳遞多個路徑參數:

Controller方法:

@RestController
public class RequestController {//路徑參數@RequestMapping("/path/{id}/{name}")public String pathParam2(@PathVariable Integer id, @PathVariable String name){System.out.println(id+ " : " +name);return "OK";}
}

二、響應

前面我們學習過HTTL協議的交互方式:請求響應模式(有請求就有響應)

那么Controller程序呢,除了接收請求外,還可以進行響應。

2.1 @ResponseBody

在我們前面所編寫的controller方法中,都已經設置了響應數據。

controller方法中的return的結果,使用了@ResponseBody注解響應給瀏覽器。

@ResponseBody注解:

  • 類型:方法注解、類注解

  • 位置:書寫在Controller方法上或類上

  • 作用:將方法返回值直接響應給瀏覽器

    • 如果返回值類型是實體對象/集合,將會轉換為JSON格式后在響應給瀏覽器

但是在我們所書寫的Controller中,只在類上添加了@RestController注解、方法添加了@RequestMapping注解,并沒有使用@ResponseBody注解,怎么給瀏覽器響應呢?

@RestController
public class HelloController {@RequestMapping("/hello")public String hello(){System.out.println("Hello World ~");return "Hello World ~";}
}

原因:在類上添加的@RestController注解,是一個組合注解。

  • @RestController = @Controller + @ResponseBody

結論:在類上添加@RestController就相當于添加了@ResponseBody注解。

  • 類上有@RestController注解或@ResponseBody注解時:表示當前類下所有的方法返回值做為響應數據

    • 方法的返回值,如果是一個POJO對象或集合時,會先轉換為JSON格式,在響應給瀏覽器

2.2 統一響應結果

大家有沒有發現一個問題,我們在前面所編寫的這些Controller方法中,返回值各種各樣,沒有任何的規范。

?在真實的項目開發中,我們會定義一個統一的返回結果。方案如下:

前端:只需要按照統一格式的返回結果進行解析(僅一種解析方案),就可以拿到數據。

統一的返回結果使用類來描述,在這個結果中包含:

  • 響應狀態碼:當前請求是成功,還是失敗

  • 狀態碼信息:給頁面的提示信息

  • 返回的數據:給前端響應的數據(字符串、對象、集合)

定義在一個實體類Result來包含以上信息。代碼如下:

public class Result {private Integer code;//響應碼,1 代表成功; 0 代表失敗private String msg;  //響應碼 描述字符串private Object data; //返回的數據public Result() { }public Result(Integer code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}//增刪改 成功響應(不需要給前端返回數據)public static Result success(){return new Result(1,"success",null);}//查詢 成功響應(把查詢結果做為返回數據響應給前端)public static Result success(Object data){return new Result(1,"success",data);}//失敗響應public static Result error(String msg){return new Result(0,msg,null);}
}

改造Controller:

@RestController
public class ResponseController { //響應統一格式的結果@RequestMapping("/hello")public Result hello(){System.out.println("Hello World ~");//return new Result(1,"success","Hello World ~");return Result.success("Hello World ~");}//響應統一格式的結果@RequestMapping("/getAddr")public Result getAddr(){Address addr = new Address();addr.setProvince("廣東");addr.setCity("深圳");return Result.success(addr);}//響應統一格式的結果@RequestMapping("/listAddr")public Result listAddr(){List<Address> list = new ArrayList<>();Address addr = new Address();addr.setProvince("廣東");addr.setCity("深圳");Address addr2 = new Address();addr2.setProvince("陜西");addr2.setCity("西安");list.add(addr);list.add(addr2);return Result.success(list);}
}

使用Postman測試:

三、分層解耦

3.1 三層架構

在我們進行程序設計以及程序開發時,盡可能讓每一個接口、類、方法的職責更單一些(單一職責原則)。

單一職責原則:一個類或一個方法,就只做一件事情,只管一塊功能。

這樣就可以讓類、接口、方法的復雜度更低,可讀性更強,擴展性更好,也更利用后期的維護。

我們之前開發的程序呢,并不滿足單一職責原則。下面我們來分析下下面的程序:

那其實我們上述案例的處理邏輯呢,從組成上看可以分為三個部分:

  • 數據訪問:負責業務數據的維護操作,包括增、刪、改、查等操作。

  • 邏輯處理:負責業務邏輯處理的代碼。

  • 請求處理、響應數據:負責,接收頁面的請求,給頁面響應數據。

按照上述的三個組成部分,在我們項目開發中呢,可以將代碼分為三層:

  • Controller:控制層。接收前端發送的請求,對請求進行處理,并響應數據。

  • Service:業務邏輯層。處理具體的業務邏輯。

  • Dao:數據訪問層(Data Access Object),也稱為持久層。負責數據訪問操作,包括數據的增、刪、改、查。

基于三層架構的程序執行流程:

  • 前端發起的請求,由Controller層接收(Controller響應數據給前端)

  • Controller層調用Service層來進行邏輯處理(Service層處理完后,把處理結果返回給Controller層)

  • Serivce層調用Dao層(邏輯處理過程中需要用到的一些數據要從Dao層獲取)

  • Dao層操作文件中的數據(Dao拿到的數據會返回給Service層)

思考:按照三層架構的思想,如何要對業務邏輯(Service層)進行變更,會影響到Controller層和Dao層嗎?

答案:不會影響。 (程序的擴展性、維護性變得更好了)

3.2 分層解耦

解耦:解除耦合。

耦合問題

首先需要了解軟件開發涉及到的兩個概念:內聚和耦合。

  • 內聚:軟件中各個功能模塊內部的功能聯系。

  • 耦合:衡量軟件中各個層/模塊之間的依賴、關聯的程度。

軟件設計原則:高內聚低耦合。

高內聚指的是:一個模塊中各個元素之間的聯系的緊密程度,如果各個元素(語句、程序段)之間的聯系程度越高,則內聚性越高,即 "高內聚"。

低耦合指的是:軟件中各個層、模塊之間的依賴關聯程序越低越好。

程序中高內聚的體現:

  • EmpServiceA類中只編寫了和員工相關的邏輯處理代碼

程序中耦合代碼的體現:

  • 把業務類變為EmpServiceB時,需要修改controller層中的代碼

?高內聚、低耦合的目的是使程序模塊的可重用性、移植性大大增強。

解耦思路

之前我們在編寫代碼時,需要什么對象,就直接new一個就可以了。 這種做法呢,層與層之間代碼就耦合了,當service層的實現變了之后, 我們還需要修改controller層的代碼。

  • ?首先不能在EmpController中使用new對象。代碼如下:

  • 此時,就存在另一個問題了,不能new,就意味著沒有業務層對象(程序運行就報錯),怎么辦呢?

    • 我們的解決思路是:

      • 提供一個容器,容器中存儲一些對象(例:EmpService對象)

      • controller程序從容器中獲取EmpService類型的對象

我們想要實現上述解耦操作,就涉及到Spring中的兩個核心概念:

  • 控制反轉: Inversion Of Control,簡稱IOC。對象的創建控制權由程序自身轉移到外部(容器),這種思想稱為控制反轉。

    對象的創建權由程序員主動創建轉移到容器(由容器創建、管理對象)。這個容器稱為:IOC容器或Spring容器

  • 依賴注入: Dependency Injection,簡稱DI。容器為應用程序提供運行時,所依賴的資源,稱之為依賴注入。

    程序運行時需要某個資源,此時容器就為其提供這個資源。

    例:EmpController程序運行時需要EmpService對象,Spring容器就為其提供并注入EmpService對象

IOC容器中創建、管理的對象,稱之為:bean對象

3.3 IOC&DI

上面我們引出了Spring中IOC和DI的基本概念,下面我們就來具體學習下IOC和DI的代碼實現。

IOC&DI入門

任務:完成Controller層、Service層、Dao層的代碼解耦

  • 思路:

    1. 刪除Controller層、Service層中new對象的代碼

    2. Service層及Dao層的實現類,交給IOC容器管理

    3. 為Controller及Service注入運行時依賴的對象

      • Controller程序中注入依賴的Service層對象

      • Service程序中注入依賴的Dao層對象

第1步:刪除Controller層、Service層中new對象的代碼

第2步:Service層及Dao層的實現類,交給IOC容器管理

  • 使用Spring提供的注解:@Component ,就可以實現類交給IOC容器管理

第3步:為Controller及Service注入運行時依賴的對象

  • 使用Spring提供的注解:@Autowired ,就可以實現程序運行時IOC容器自動注入需要的依賴對象

完整的三層代碼:

  • Controller層:

@RestController
public class EmpController {@Autowired //運行時,從IOC容器中獲取該類型對象,賦值給該變量private EmpService empService ;@RequestMapping("/listEmp")public Result list(){//1. 調用service, 獲取數據List<Emp> empList = empService.listEmp();//3. 響應數據return Result.success(empList);}
}
  • Service層:
@Component //將當前對象交給IOC容器管理,成為IOC容器的bean
public class EmpServiceA implements EmpService {@Autowired //運行時,從IOC容器中獲取該類型對象,賦值給該變量private EmpDao empDao ;@Overridepublic List<Emp> listEmp() {//1. 調用dao, 獲取數據List<Emp> empList = empDao.listEmp();//2. 對數據進行轉換處理 - gender, jobempList.stream().forEach(emp -> {//處理 gender 1: 男, 2: 女String gender = emp.getGender();if("1".equals(gender)){emp.setGender("男");}else if("2".equals(gender)){emp.setGender("女");}//處理job - 1: 講師, 2: 班主任 , 3: 就業指導String job = emp.getJob();if("1".equals(job)){emp.setJob("講師");}else if("2".equals(job)){emp.setJob("班主任");}else if("3".equals(job)){emp.setJob("就業指導");}});return empList;}
}
  • Dao層:
@Component //將當前對象交給IOC容器管理,成為IOC容器的bean
public class EmpDaoA implements EmpDao {@Overridepublic List<Emp> listEmp() {//1. 加載并解析emp.xmlString file = this.getClass().getClassLoader().getResource("emp.xml").getFile();System.out.println(file);List<Emp> empList = XmlParserUtils.parse(file, Emp.class);return empList;}
}

IOC詳解

通過IOC和DI的入門程序呢,我們已經基本了解了IOC和DI的基礎操作。接下來呢,我們學習下IOC控制反轉和DI依賴注入的細節。

bean的聲明

前面我們提到IOC控制反轉,就是將對象的控制權交給Spring的IOC容器,由IOC容器創建及管理對象。IOC容器創建的對象稱為bean對象。

在之前的入門案例中,要把某個對象交給IOC容器管理,需要在類上添加一個注解:@Component

而Spring框架為了更好的標識web應用程序開發當中,bean對象到底歸屬于哪一層,又提供了@Component的衍生注解:

  • @Controller (標注在控制層類上)

  • @Service (標注在業務層類上)

  • @Repository (標注在數據訪問層類上)

修改入門案例代碼:

  • Controller層:

    @RestController  //@RestController = @Controller + @ResponseBody
    public class EmpController {@Autowired //運行時,從IOC容器中獲取該類型對象,賦值給該變量private EmpService empService ;@RequestMapping("/listEmp")public Result list(){//1. 調用service, 獲取數據List<Emp> empList = empService.listEmp();//3. 響應數據return Result.success(empList);}
    }
  • Service層:

@Service
public class EmpServiceA implements EmpService {@Autowired //運行時,從IOC容器中獲取該類型對象,賦值給該變量private EmpDao empDao ;@Overridepublic List<Emp> listEmp() {//1. 調用dao, 獲取數據List<Emp> empList = empDao.listEmp();//2. 對數據進行轉換處理 - gender, jobempList.stream().forEach(emp -> {//處理 gender 1: 男, 2: 女String gender = emp.getGender();if("1".equals(gender)){emp.setGender("男");}else if("2".equals(gender)){emp.setGender("女");}//處理job - 1: 講師, 2: 班主任 , 3: 就業指導String job = emp.getJob();if("1".equals(job)){emp.setJob("講師");}else if("2".equals(job)){emp.setJob("班主任");}else if("3".equals(job)){emp.setJob("就業指導");}});return empList;}
}
  • Dao層

@Repository
public class EmpDaoA implements EmpDao {@Overridepublic List<Emp> listEmp() {//1. 加載并解析emp.xmlString file = this.getClass().getClassLoader().getResource("emp.xml").getFile();System.out.println(file);List<Emp> empList = XmlParserUtils.parse(file, Emp.class);return empList;}
}

要把某個對象交給IOC容器管理,需要在對應的類上加上如下注解之一:

注解說明位置
@Controller@Component的衍生注解標注在控制器類上
@Service@Component的衍生注解標注在業務類上
@Repository@Component的衍生注解標注在數據訪問類上(由于與mybatis整合,用的少)
@Component聲明bean的基礎注解不屬于以上三類時,用此注解

在IOC容器中,每一個Bean都有一個屬于自己的名字,可以通過注解的value屬性指定bean的名字。如果沒有指定,默認為類名首字母小寫。

注意事項:

  • 聲明bean的時候,可以通過value屬性指定bean的名字,如果沒有指定,默認為類名首字母小寫。

  • 使用以上四個注解都可以聲明bean,但是在springboot集成web開發中,聲明控制器bean只能用@Controller。

組件掃描

問題:使用前面學習的四個注解聲明的bean,一定會生效嗎?

答案:不一定。(原因:bean想要生效,還需要被組件掃描)

下面我們通過修改項目工程的目錄結構,來測試bean對象是否生效:

運行程序后,報錯:

為什么沒有找到bean對象呢?

  • 使用四大注解聲明的bean,要想生效,還需要被組件掃描注解@ComponentScan掃描

@ComponentScan注解雖然沒有顯式配置,但是實際上已經包含在了引導類聲明注解 @SpringBootApplication 中,==默認掃描的范圍是SpringBoot啟動類所在包及其子包==。

  • 解決方案:手動添加@ComponentScan注解,指定要掃描的包 (==僅做了解,不推薦==)

推薦做法(如下圖):

  • 將我們定義的controller,service,dao這些包呢,都放在引導類所在包com.itheima的子包下,這樣我們定義的bean就會被自動的掃描到

DI詳解

上一小節我們講解了控制反轉IOC的細節,接下來呢,我們學習依賴注解DI的細節。

依賴注入,是指IOC容器要為應用程序去提供運行時所依賴的資源,而資源指的就是對象。

在入門程序案例中,我們使用了@Autowired這個注解,完成了依賴注入的操作,而這個Autowired翻譯過來叫:自動裝配。

@Autowired注解,默認是按照類型進行自動裝配的(去IOC容器中找某個類型的對象,然后完成注入操作)

入門程序舉例:在EmpController運行的時候,就要到IOC容器當中去查找EmpService這個類型的對象,而我們的IOC容器中剛好有一個EmpService這個類型的對象,所以就找到了這個類型的對象完成注入操作。

那如果在IOC容器中,存在多個相同類型的bean對象,會出現什么情況呢?

  • 程序運行會報錯

如何解決上述問題呢?Spring提供了以下幾種解決方案:

  • @Primary

  • @Qualifier

  • @Resource

使用@Primary注解:當存在多個相同類型的Bean注入時,加上@Primary注解,來確定默認的實現。

使用@Qualifier注解:指定當前要注入的bean對象。 在@Qualifier的value屬性中,指定注入的bean的名稱。

  • @Qualifier注解不能單獨使用,必須配合@Autowired使用

使用@Resource注解:是按照bean的名稱進行注入。通過name屬性指定要注入的bean的名稱。

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

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

相關文章

競爭性學習:無監督世界的智能聚類引擎

一、競爭性學習&#xff1a;無監督聚類的生物啟發范式 1.1 核心原理&#xff1a;神經元的 “適者生存” 競爭性學習模擬生物神經網絡的競爭機制&#xff1a;多個神經元對輸入數據 “競爭響應”&#xff0c;獲勝神經元&#xff08;與輸入最匹配&#xff09;更新權重&#xff0…

docker面試題(5)

Docker安全么 Docker 利用了 Linux 內核中很多安全特性來保證不同容器之間的隔離&#xff0c;并且通過簽名機制來對鏡像進行 驗證。大量生產環境的部署證明&#xff0c;Docker 雖然隔離性無法與虛擬機相比&#xff0c;但仍然具有極高的安全性。 如何清理后臺停止的容器 可以使用…

同為科技 智能PDU產品選型介紹 EN10/I801CI

智能PDU是一種利用信息技術手段&#xff0c;優化電力的分配和使用。隨著數據中心進行虛擬化部署和為提高計算效率而整合設備&#xff0c;平均機架功率密度在持續增長&#xff0c;幾年前&#xff0c;一個普通機柜需要3-4千瓦電力&#xff0c;而現今9-15千瓦甚至更高電力的機柜則…

Aciviti工作流

1. springBoot和activiti整合 pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"…

golang 對象池sync.Pool的實現

Go語言中sync.Pool通過多級緩存機制實現高效對象復用&#xff0c;其核心設計結合了GMP調度模型特性。以下是實現要點分析&#xff1a; P o o l ∑ p 0 G O M A X P R O C S ( l o c a l P o o l p ) v i c t i m C a c h e Pool \sum_{p0}^{GOMAXPROCS}(localPool_p) vict…

Docker run命令-p參數詳解

端口映射基礎語法 docker run -p <宿主機端口>:<容器端口> 操作示例 docker run -d --restartalways --namespug -p 5000:80 registry.aliyuncs.com/openspug/spug參數解析 -d&#xff1a;后臺運行容器--restartalways&#xff1a;設置容器自動重啟--namespug&…

《2.1.4 C語言中的整數類型及類型轉換|精講篇》

后面作者會在2025.5.25 00:00前整理出筆記和思維導圖大家放心&#xff0c;主頁還有其他文章 請先移步歡迎參考 收藏文章 關注博主 高效學習 好了&#xff0c;這小節我們要探討一個相對來說簡單的問題&#xff0c;就是C語言里邊的那些定點整數是如何進行強制類型轉換的。好來看這…

采用多維計算策略(分子動力學模擬+機器學習),顯著提升 α-半乳糖苷酶熱穩定性

字數 978&#xff0c;閱讀大約需 5 分鐘 在工業應用領域&#xff0c;α-半乳糖苷酶在食品加工、動物營養及醫療等方面發揮著重要作用。然而&#xff0c;微生物來源的該酶往往存在熱穩定性不足的問題&#xff0c;限制了其在工業場景中的高效應用。近日&#xff0c;來自江南大學的…

Jetpack Compose預覽調試技巧

Jetpack Compose 預覽(Preview)不顯示是一個常見問題,可能由多種原因導致。以下是系統的調試技巧和解決方案: 1. 檢查基礎配置 Compose 版本兼容性 確保 compose-compiler、compose-ui 等依賴版本一致且與 Kotlin 版本兼容。檢查 build.gradle: android {compileOptions {…

使用 Go 語言實現完整且輕量級高性能的 MQTT Broker

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一種輕量級的發布/訂閱消息傳輸協議。但是目前雖然mqtt的客戶端很多&#xff0c;但是服務端著實不多&#xff0c;常見的服務端如mosquitto或emqx。但是golang語言的實現幾乎找不到。golang的輕量級部署和高并…

uv sync --frozen卡住不動

今天受邀幫同事調試uv卡住不動的問題&#xff0c;同樣的代碼已經在別的服務器跑起來了&#xff0c;換了一臺服務器之后&#xff0c;執行uv sync --frozen沒有按預期創建虛擬環境和安裝依賴。 1. 鏡像源是已經配置好的&#xff0c;pip install也能很快安裝包。 2. 查看了uv.lo…

Spring Boot中如何對密碼等敏感信息進行脫敏處理

以下是常見的脫敏方法及實現步驟&#xff0c;涵蓋配置、日志和API響應等多個層面&#xff1a; ?1. 配置文件敏感信息脫敏? (1) 使用加密庫&#xff08;如Jasypt&#xff09; ?步驟?&#xff1a; 添加依賴&#xff1a; <dependency><groupId>com.github.ulise…

springboot中redis的事務的研究

redis的事務類似于隊列操作&#xff0c;執行過程分為三步&#xff1a; 開啟事務入隊操作執行事務 使用到的幾個命令如下&#xff1a; 命令說明multi開啟一個事務exec事務提交discard事務回滾watch監聽key(s)&#xff1a;當監聽一個key(s)時&#xff0c;如果在本次事務提交之…

python打卡day35@浙大疏錦行

知識點回顧&#xff1a; 三種不同的模型可視化方法&#xff1a;推薦torchinfo打印summary權重分布可視化進度條功能&#xff1a;手動和自動寫法&#xff0c;讓打印結果更加美觀推理的寫法&#xff1a;評估模式 作業&#xff1a;調整模型定義時的超參數&#xff0c;對比下效果。…

Python爬蟲實戰:研究Crawley 框架相關技術

1. Crawley 框架相關定義 1.1 網絡爬蟲定義 網絡爬蟲是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。它通過 HTTP 協議與 Web 服務器進行交互,獲取網頁內容并進行解析處理,是數據采集和信息檢索的重要工具。 1.2 Crawley 框架定義 Crawley 是一個基于 Pytho…

tvalid寄存器的理解

if(!out_axis_tvalid_reg || m_axis_tready ) beginend m_axis_tready 是上拍下一級給的ready信號 out_axis_tvalid_reg是上一拍&#xff0c;本級給下級的valid信號 一共有四種組合&#xff0c;然后可以通過這個if語句&#xff0c;在接下來的begin ... end中&#xff0c;用來…

【AI實戰】從“苦AI”到“爽AI”:Magentic-UI 把“人類-多智能體協作”玩明白了!

Hello&#xff0c;親愛的小伙伴們&#xff01;你是否曾經在深夜里&#xff0c;為了自動化點外賣、篩機票、抓網頁數據焦頭爛額&#xff1f;有沒有幻想過哪天能出個“貼心AI管家”&#xff0c;一鍵點菜、搞定事務、自動操作網頁&#xff0c;比你還懂你&#xff1f;更關鍵——還讓…

【東楓科技】usrp rfnoc 開發環境搭建

作者 太原市東楓電子科技有限公司 &#xff0c;代理銷售 USRP&#xff0c;Nvidia&#xff0c;等產品與技術支持&#xff0c;培訓服務。 環境 Ubuntu 20.04 依賴包 sudo apt-get updatesudo apt-get install autoconf automake build-essential ccache cmake cpufrequtils …

Ntfs!ReadIndexBuffer函數分析之根目錄讀取索引緩沖區的一個例子

Ntfs!ReadIndexBuffer函數分析之根目錄讀取索引緩沖區的一個例子 第一部分&#xff1a; 0: kd> p Ntfs!ReadIndexBuffer0xdc: f7173962 e829f60300 call Ntfs!NtfsCheckIndexBuffer (f71b2f90) 0: kd> t Ntfs!NtfsCheckIndexBuffer: f71b2f90 55 p…

LumaDot (亮度可調的屏幕圓點)

應用名稱 LumaDot &#xff08;源自 “Luminance”&#xff08;亮度&#xff09; “Dot”&#xff08;圓點&#xff09;&#xff0c;強調其核心功能&#xff1a;亮度可調的屏幕圓點&#xff09; 應用說明 LumaDot 是一款輕量級 Windows 桌面工具&#xff0c;專為需要屏幕標記…