微服務網關組件Gateway實戰

1. 需求背景

在微服務架構中,通常一個系統會被拆分為多個微服務,面對這么多微服務客戶端應該如何去調用呢?如果根據每個微服務的地址發起調用,存在如下問題:

  1. 客戶端多次請求不同的微服務,會增加客戶端代碼和配置的復雜性,維護成本比價高
  2. 認證復雜,每個微服務可能存在不同的認證方式,客戶端去調用,要去適配不同的認證
  3. 存在跨域的請求,調用鏈有一定的相對復雜性(防火墻 / 瀏覽器不友好的協議)
  4. 難以重構,隨著項目的迭代,可能需要重新劃分微服務

為了解決上面的問題,微服務引入了API網關的概念,API網關為微服務架構的系統提供簡單、有效且統一的API路由管理,作為系統的統一入口,提供內部服務的路由中轉,給客戶端提供統一的服務,可以實現一些和業務沒有耦合的公用邏輯,主要功能包含認證、鑒權、路由轉發、安全策略、防刷、流量控制、監控日志等。

2. 什么是Spring Cloud Gateway

Spring Cloud Gateway 是Spring Cloud官方推出的第二代網關框架,定位于取代 Netflix Zuul。Spring Cloud Gateway 旨在為微服務架構提供一種簡單且有效的 API 路由的管理方式,并基于 Filter 的方式提供網關的基本功能,例如說安全認證、監控、限流等等。

Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 實現的響應式的 API 網關。它不能在傳統的 servlet 容器中工作,也不能構建成 war 包。

官網文檔:Spring Cloud Gateway

2.1?核心概念

  1. 路由(route)

路由是網關中最基礎的部分,路由信息包括一個ID、一個目的URI、一組斷言工廠、一組Filter組成。

  1. 斷言(predicates)

Java8中的斷言函數,SpringCloud Gateway中的斷言函數類型是Spring5.0框架中的ServerWebExchange。斷言函數允許開發者去定義匹配Http request中的任何信息,比如請求頭和參數等。如果斷言為真,則說明請求的URL和配置的路由匹配。

  1. 過濾器(Filter)

SpringCloud Gateway中的filter分為Gateway FilIer和Global Filter。Filter可以對請求和響應進行處理。

2.2 工作原理

Spring Cloud Gateway 的工作原理跟 Zuul 的差不多,最大的區別就是 Gateway 的 Filter 只有 pre 和 post 兩種。

客戶端向 Spring Cloud Gateway 發出請求,如果請求與網關程序定義的路由匹配,則該請求就會被發送到網關 Web 處理程序,此時處理程序運行特定的請求過濾器鏈。

過濾器之間用虛線分開的原因是過濾器可能會在發送代理請求的前后執行邏輯。所有 pre 過濾器邏輯先執行,然后執行代理請求;代理請求完成后,執行 post 過濾器邏輯。

3. Spring Cloud Gateway實戰

3.1 微服務快速接入Spring Cloud Gateway

1) 引入依賴

<!-- gateway網關 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency><!-- nacos服務注冊與發現 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

注意:gateway會和spring-webmvc的依賴沖突,需要排除spring-webmvc

2) 編寫yml配置文件

spring:application:name: mall-gateway#配置nacos注冊中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一,建議配置服務名uri: lb://mall-order  #lb 整合負載均衡器loadbalancerpredicates:- Path=/order/**   # 斷言,路徑相匹配的進行路由- id: user_route   #路由ID,全局唯一,建議配置服務名uri: lb://mall-user  #lb 整合負載均衡器loadbalancerpredicates:- Path=/user/**   # 斷言,路徑相匹配的進行路由

3)測試

http://localhost:8888/order/findOrderByUserId/1

3.2 路由斷言工廠(Route Predicate Factories)配置

predicates:路由斷言,判斷請求是否符合要求,符合則轉發到路由目的地。application.yml配置文件中寫的斷言規則只是字符串,這些字符串會被Predicate Factory讀取并處理,轉變為路由判斷的條件

文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

通過網關啟動日志,可以查看內置路由斷言工廠:

3.2.1 路徑匹配

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: lb://mall-order  #目標微服務的請求地址和端口predicates:# 測試:http://localhost:8888/order/findOrderByUserId/1- Path=/order/**    # 斷言,路徑相匹配的進行路由

3.2.2 Header匹配

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: lb://mall-order  #目標微服務的請求地址和端口predicates:- Path=/order/**   # 斷言,路徑相匹配的進行路由# Header匹配  請求中帶有請求頭名為 x-request-id,其值與 \d+ 正則表達式匹配- Header=X-Request-Id, \d+

測試

3.3 過濾器工廠(?GatewayFilter?Factories)配置

GatewayFilter是網關中提供的一種過濾器,可以對進入網關的請求和微服務返回的響應做處理

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

3.3.1 添加請求頭

需求:給所有進入mall-order的請求添加一個請求頭:X-Request-color=red。

只需要修改gateway服務的application.yml文件,添加路由過濾即可:

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: http://localhost:8020  #目標微服務的請求地址和端口#配置過濾器工廠filters:- AddRequestHeader=X-Request-color, red  #添加請求頭

測試http://localhost:8888/order/testgateway

@GetMapping("/testgateway")
public String testGateway(HttpServletRequest request) throws Exception {log.info("gateWay獲取請求頭X-Request-color:"+request.getHeader("X-Request-color"));return "success";
}
@GetMapping("/testgateway2")
public String testGateway(@RequestHeader("X-Request-color") String color) throws Exception {log.info("gateWay獲取請求頭X-Request-color:"+color);return "success";
}

3.3.2 添加請求參數

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: http://localhost:8020  #目標微服務的請求地址和端口#配置過濾器工廠filters:- AddRequestParameter=color, blue  # 添加請求參數

測試http://localhost:8888/order/testgateway3

@GetMapping("/testgateway3")
public String testGateway3(@RequestParam("color") String color) throws Exception {log.info("gateWay獲取請求參數color:"+color);return "success";
}

3.3.3 自定義過濾器工廠

繼承AbstractNameValueGatewayFilterFactory且我們的自定義名稱必須要以GatewayFilterFactory結尾并交給spring管理。

@Component
@Slf4j
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Overridepublic GatewayFilter apply(NameValueConfig config) {return (exchange, chain) -> {log.info("調用CheckAuthGatewayFilterFactory==="+ config.getName() + ":" + config.getValue());return chain.filter(exchange);};}
}

配置自定義的過濾器工廠

spring:cloud:gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一uri: http://localhost:8020  #目標微服務的請求地址和端口#配置過濾器工廠filters:- CheckAuth=fox,男   #自定義過濾器工廠

測試

3.4 全局過濾器(Global Filters)配置

全局過濾器的作用也是處理一切進入網關的請求和微服務響應,與GatewayFilter的作用一樣。

  • GatewayFilter:網關過濾器,需要通過spring.cloud.routes.filters配置在具體的路由下,只作用在當前特定路由上,也可以通過配置spring.cloud.default-filters讓它作用于全局路由上。
  • GlobalFilter:全局過濾器,不需要再配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain能夠識別的過濾器。

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

3.4.1 ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter 會查看exchange的屬性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR的值(一個URI,比如lb://mall-order/order/testgateway2?color=blue),如果該值的scheme是 lb,比如:lb://myservice ,它將會使用Spring Cloud的LoadBalancerClient 來將 myservice 解析成實際的host和port。

其實就是用來整合負載均衡器loadbalancer的

spring:cloud:gateway:routes:- id: order_routeuri: lb://mall-orderpredicates:- Path=/order/**

3.4.2 自定義全局過濾器

自定義全局過濾器定義方式是實現GlobalFilter接口。每一個過濾器都必須指定一個int類型的order值,order值越小,過濾器優先級越高,執行順序越靠前。GlobalFilter通過實現Ordered接口來指定order值

@Component
@Slf4j
public class CheckAuthFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//獲取tokenString token = exchange.getRequest().getHeaders().getFirst("token");if (null == token) {log.info("token is null");ServerHttpResponse response = exchange.getResponse();response.getHeaders().add("Content-Type","application/json;charset=UTF-8");// 401 用戶沒有訪問權限response.setStatusCode(HttpStatus.UNAUTHORIZED);byte[] bytes = HttpStatus.UNAUTHORIZED.getReasonPhrase().getBytes();DataBuffer buffer = response.bufferFactory().wrap(bytes);// 請求結束,不繼續向下請求return response.writeWith(Mono.just(buffer));}//TODO 校驗token進行身份認證log.info("校驗token");return chain.filter(exchange);}@Overridepublic int getOrder() {return 2;}
}

3.5 Gateway跨域資源共享配置(CORS Configuration)

在前端領域中,跨域是指瀏覽器允許向服務器發送跨域請求,從而克服Ajax只能同源使用的限制。

同源策略(Same Orgin Policy)是一種約定,它是瀏覽器核心也最基本的安全功能,它會阻止一個域的js腳本和另外一個域的內容進行交互,如果缺少了同源策略,瀏覽器很容易受到XSS、CSRF等攻擊。所謂同源(即在同一個域)就是兩個頁面具有相同的協議(protocol)、主機(host)和端口號(port)。

CORS: 跨源資源共享(CORS) - HTTP | MDN

測試代碼

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body><div ><table border="1"><thead><tr><th>id</th><th>userId</th><th>commodityCode</th><th>count</th><th>amount</th></tr></thead><tbody id="orderlist"></tbody></table></div><input type="button" value="訂單列表" onclick="getData()"><script>function getData() {$.get('http://localhost:8888/order/findOrderByUserId/1',function(data){console.log(data.orders)var list = data.orders;var str = '';for(var i=0;i<list.length;i++){str +='<tr><th>'+list[i].id+'</th><th>'+list[i].userId+'</th><th>'+list[i].commodityCode+'</th><th>'+list[i].count+'</th><th>'+list[i].amount+'</th></tr>';}$('#orderlist').html(str);});}</script>
</body>
</html>

測試結果

如何解決gateway跨域問題?

通過yml配置的方式

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTION

通過java配置的方式

@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}

3.6 Gateway基于redis+lua腳本限流

spring cloud官方提供了RequestRateLimiter過濾器工廠,基于redis+lua腳本方式采用令牌桶算法實現了限流。

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-requestratelimiter-gatewayfilter-factory

請求不被允許時返回狀態:HTTP 429 - Too Many Requests。

1)添加依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

2)修改?application.yml?,添加redis配置和RequestRateLimiter過濾器工廠配置

spring:application:name: mall-gatewaydata:#配置redis地址redis:host: localhostport: 6379database: 0timeout: 5000lettuce:pool:max-active: 200max-wait: 10000max-idle: 100min-idle: 10#配置nacos注冊中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一,建議配置服務名# 測試 http://localhost:8888/order/findOrderByUserId/1uri: lb://mall-order  #lb 整合負載均衡器ribbon,loadbalancerpredicates:- Path=/order/**   # 斷言,路徑相匹配的進行路由#配置過濾器工廠filters:- name: RequestRateLimiter   #限流過濾器args:redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充速率redis-rate-limiter.burstCapacity: 2 #令牌桶的總容量key-resolver: "#{@keyResolver}" #使用SpEL表達式,從Spring容器中獲取Bean對象 

3) 配置keyResolver,可以指定限流策略,比如url限流,參數限流,ip限流等等

@Bean
KeyResolver keyResolver() {//url限流return exchange -> Mono.just(exchange.getRequest().getURI().getPath());//參數限流//return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

4) 測試

url限流:http://localhost:8888/order/findOrderByUserId/1?

參數限流:http://localhost:8888/order/findOrderByUserId/1?user=fox

3.7 Gateway整合sentinel限流

從 1.6.0 版本開始,Sentinel 提供了 Spring Cloud Gateway 的適配模塊,可以提供兩種資源維度的限流:

  1. route 維度:即在 Spring 配置文件中配置的路由條目,資源名為對應的 routeId
  2. 自定義 API 維度:用戶可以利用 Sentinel 提供的 API 來自定義一些 API 分組

sentinel網關流控:api-gateway-flow-control | Sentinel

3.7.1 Gateway整合sentinel實現網關限流

1)引入依賴

<!-- gateway接入sentinel  -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2)添加yml配置,接入sentinel dashboard,通過sentinel控制臺配置網關流控規則

server:port: 8888
spring:application:name: mall-gateway-sentinel-demomain:allow-bean-definition-overriding: true#配置nacos注冊中心地址cloud:nacos:discovery:server-addr: 127.0.0.1:8848sentinel:transport:# 添加sentinel的控制臺地址dashboard: 127.0.0.1:8080gateway:#設置路由:路由id、路由到微服務的uri、斷言routes:- id: order_route  #路由ID,全局唯一,建議配合服務名uri: lb://mall-order  #lb 整合負載均衡器loadbalancerpredicates:- Path=/order/**- id: user_routeuri: lb://mall-user  #lb 整合負載均衡器loadbalancerpredicates:- Path=/user/**

注意:基于SpringBoot3的 Spring Cloud Gateway和Sentinel還存在兼容性問題,等待Sentinel官方對最新的Gateway適配包更新

3.7.2 Sentinel網關流控實現原理

當通過?GatewayRuleManager?加載網關流控規則(GatewayFlowRule)時,無論是否針對請求屬性進行限流,Sentinel 底層都會將網關流控規則轉化為熱點參數規則(ParamFlowRule),存儲在?GatewayRuleManager?中,與正常的熱點參數規則相隔離。轉換時 Sentinel 會根據請求屬性配置,為網關流控規則設置參數索引(idx),并同步到生成的熱點參數規則中。

外部請求進入 API Gateway 時會經過 Sentinel 實現的 filter,其中會依次進行?路由/API 分組匹配、請求屬性解析和參數組裝。Sentinel 會根據配置的網關流控規則來解析請求屬性,并依照參數索引順序組裝參數數組,最終傳入?SphU.entry(res, args)?中。Sentinel API Gateway Adapter Common 模塊向 Slot Chain 中添加了一個?GatewayFlowSlot,專門用來做網關規則的檢查。GatewayFlowSlot?會從?GatewayRuleManager?中提取生成的熱點參數規則,根據傳入的參數依次進行規則檢查。若某條規則不針對請求屬性,則會在參數最后一個位置置入預設的常量,達到普通流控的效果。

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

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

相關文章

聚首引領行業風潮!聚首品牌聯動資源價值平臺發布會正式啟航

2023年12月10日&#xff0c;由杭州建筑裝飾學會、浙江聚首聯優材料科技有限公司主辦&#xff0c;天尚設計集團、公和設計集團、銘揚工程設計集團、地標設計集團、上宸工程設計集團、華坤建筑設計院、廣廈建筑設計研究院、上海傳承博華建筑規劃設計院、航冠工程設計院、浙江鴻能…

Github項目-CNNResnet9-殘差神經網絡水果多分類項目

ResNet-論文全文完整翻譯注解 - 知乎 你必須要知道CNN模型&#xff1a;ResNet - 知乎 #!/usr/bin/env python # coding: utf-8 #https://github.com/SehajS/cnn-resnet-fruit-classification # # Classifying Fruits from their Images # # This project aims at creating a…

設計模式——建造者模式(創建型)

引言 生成器模式是一種創建型設計模式&#xff0c; 使你能夠分步驟創建復雜對象。 該模式允許你使用相同的創建代碼生成不同類型和形式的對象。 問題 假設有這樣一個復雜對象&#xff0c; 在對其進行構造時需要對諸多成員變量和嵌套對象進行繁復的初始化工作。 這些初始化代碼…

Python3開發環境的搭建

1&#xff0c;電腦操作系統的確認 我的是win10、64位的&#xff0c;你們的操作系統可自尋得。 2&#xff0c;Python安裝包的下載 &#xff08;1&#xff09;瀏覽器種輸入網址&#xff1a;https://www.python.org 選擇對應的系統&#xff08;我的是win10/64位) &#xf…

設計模式(二)-創建者模式(5)-建造者模式

一、為何需要建造者模式&#xff08;Builder&#xff09;? 在軟件系統中&#xff0c;會存在一個復雜的對象&#xff0c;復雜在于該對象包含了很多不同的功能模塊。該對象里的各個部分都是按照一定的算法組合起來的。 為了要使得復雜對象里的各個部分的獨立性&#xff0c;以及…

騰訊物聯網平臺之規則引擎

1.騰訊物聯網平臺簡介 騰訊云物聯網開發平臺&#xff08;IoT Explorer&#xff09;為客戶提供便捷的物聯網開發工具與服務&#xff0c;助力客戶更高效的完成設備接入&#xff0c;并為客戶提供物聯網應用開發及場景服務能力&#xff0c;幫助客戶高效、低成本構建物聯網應用。 ?…

SpringBoot集成系列--RabbitMQ

文章目錄 一、代碼1、添加依賴2、配置RabbitMQ連接3、RabbitMQ配置4、創建生產者5、創建消費者6、測試 二、遇到的問題1、Channel shutdown2、收不到信息3、安裝RabbitMQ&#xff0c;無法訪問控制臺訪問 一、代碼 1、添加依賴 在pom.xml文件中添加RabbitMQ的相關依賴 <de…

uniapp flex:1不生效

包裹view頂層 不能添加 display: flex;<template><view class"container"><tHeader :title"采購管理" :showScrollTar"true" :scroll"scroll" :tabList"tabList" :isFixed"true"change"chang…

<軟考高項備考>《論文專題 - 2 項目選材》

1 AI輔助寫作 AI技術輔助論文寫作包括&#xff1a; 1、百度-文心一言 2、阿里-千義通問 3、科大訊飛-星火認知大模型 4、騰訊-混元大模型 5、ChatGPT 可以輔助論文的選題&#xff0c;架構理論部分的思路&#xff0c;熟悉了解項目中的難點和痛點&#xff0c;拓寬論文的寫作思路…

跟我學c++高級篇——靜態反射實現之二函數接口實現

一、函數反射 在實際的編程中&#xff0c;類和結構體應用最多&#xff0c;但也最難。這里先分析函數反射&#xff0c;類和結構體放到后面在分析。函數是什么&#xff1f;其實在PC看來就是一個地址&#xff0c;在編譯順看來就是一個符號&#xff08;廢話啊&#xff09;。函數反…

Leetcode—228.匯總區間【簡單】

2023每日刷題&#xff08;五十六&#xff09; Leetcode—228.匯總區間 解題思路 我們可以用雙指針left 和 right找出每個區間的左右端點。 遍歷數組&#xff0c;當right 1< n 且 nums[right1]nums[right]1 時&#xff0c;指針right向右移動&#xff0c;否則區間 [left, …

Mysql8和Oracle實際項目中遞歸查詢樹形結構

背景&#xff1a; 項目升級&#xff0c;引入MySQL數據庫&#xff0c;之前一直用的是Oracle數據&#xff0c;在做用戶登錄單位維護的時候&#xff0c;需要返回該用戶所屬單位下的所有子單位。下邊是模擬項目數據實踐的過程。 數據準備&#xff1a; 準備一張單位表&#xff0c…

Flask存儲在內存中的密鑰被讀取

局限性&#xff1a;查找的密鑰具有特征碼 一、Flask環境源碼 1.Flask主文件main.py import os import uuid from flask import Flask, request, session, render_template from cat import catflag "" app Flask(__name__,static_url_path/,static_folderstatic …

51.Go操作kafka示例(kafka-go庫)

文章目錄 一、簡介二、生產者三、消費者 代碼地址&#xff1a;https://gitee.com/lymgoforIT/golang-trick/tree/master/31-kafka-go 一、簡介 之前已經介紹過一個操作kafka的go庫了&#xff0c;28.windows安裝kafka&#xff0c;Go操作kafka示例&#xff08;sarama庫&#xf…

二叉搜索樹的最近公共祖先【數據結構】

二叉搜索樹的最近公共祖先 題目描述 給定一棵二叉搜索樹的先序遍歷序列&#xff0c;要求你找出任意兩結點的最近公共祖先結點&#xff08;簡稱 LCA&#xff09;。 輸入 輸入的第一行給出兩個正整數&#xff1a;待查詢的結點對數 M&#xff08;≤ 1 000&#xff09;和二叉搜索…

基于JavaWeb+SpringBoot+Vue在線拍賣系統的設計和實現

基于JavaWebSpringBootVue在線拍賣系統系統的設計和實現 源碼獲取入口Lun文目錄前言主要技術系統設計功能截圖訂閱經典源碼專欄Java項目精品實戰案例《500套》 源碼獲取 源碼獲取入口 Lun文目錄 摘 要 1 Abstract 1 1 系統概述 4 1.1 概述 4 1.2課題意義 4 1.3 主要內容 4 2 …

Git命令---綁定遠程倉庫

介紹 使用git命令綁定遠程倉庫 命令 git remote add origin https://gitee.com/x.xx.com/test.git

什么是多態

/*** Description 什么是多態*/ package com.oop;import com.oop.demo06.Person; import com.oop.demo06.Student;public class Application {public static void main(String[] args) {//一個對象的實際類型是確定的//new Student();//new Person();//可以指向的引用類型就不確…

C++新經典模板與泛型編程:策略技術中的算法策略

策略技術中的算法策略 在之前博客中funcsum()函數模板中&#xff0c;實現了對數組元素的求和運算。求和在這里可以看作一種算法&#xff0c;擴展一下思路&#xff0c;對數組元素求差、求乘積、求最大值和最小值等&#xff0c;都可以看作算法。而當前的funcsum()函數模板中&…

MySQL使用教程

數據構成了我們日益數字化的社會基礎。想象一下&#xff0c;從移動應用和銀行系統到搜索引擎&#xff0c;再到如 ChatGPT 這樣的先進人工智能聊天機器人&#xff0c;這些工具若沒有數據支撐&#xff0c;將寸步難行。你有沒有好奇過這些海量數據都存放在哪里呢&#xff1f;答案正…