SpringCloud-Gateway的详细讲解以及完整的示意图和代码-下

news2024/11/6 11:22:55

目录

二说Gateway 路由配置

创建com/springcloud/config/GateWayRoutesConfig.java 

测试

动态路由

示意图 

代码实现

测试

注意事项和细节

代码

Predicate/断言

基本介绍

Route Predicate Factories

解读

Route Predicate 实例

After Route Predicate

测试

Before Route Predicate

Between Route Predicate

 Cookie Route Predicate

Header Route Predicate

Host Route Predicate

​编辑Method Route Predicate

Path Route Predicate

Query Route Predicate

 RemoteAddr Route Predicate

 Filter/过滤器

基本介绍

解读

类型

1 GatewayFilter

2 GlobalFilter 

GatewayFilter 使用

​编辑

2. 修改e-commerce-gateway-20000 的application.yml

3. 验证

自定义GlobalFilter

代码实现

测试


SpringCloud-Gateway的详细讲解以及完整的示意图和代码演示-下

二说Gateway 路由配置

1 方式1: application.yml 中配置-前面讲过
2 方式2: 编写配置类注入【了解】

先注销application.yml 对网关路由部分注销 网关部分只保留

spring:
  application:
    name: e-commerce-gateway

2. 重启e-commerce-gateway-20000, 再次测试,网关路由失效

3. 参考官方文档

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#spring-cloud-circuitbreaker-filter-factory ,

创建com/springcloud/config/GateWayRoutesConfig.java 

@Configuration
public class GateWayRoutesConfig {

   //配置注入路由

   /**
    * 在理解通过配置类注入/配置 路由,可以对照前面的application.yml来对比理解
    * cloud:
    *     gateway:
    *       routes: #配置路由,可以配置多个路由 List<RouteDefinition> routes
    *         - id: member_route01 #路由的id, 程序员自己配置,要求唯一
    *           #gateway 最终访问的url 是 url=uri+Path
    *           #匹配后提供服务的路由地址: 也可以是外网 http://www.baidu.com
    *           #比如: 客户端/浏览器请求 url http://localhost:20000/member/get/1
    *           #如果根据Path匹配成功 最终访问的url/转发url 就是 url=http://localhost:10000/member/get/1
    *           #如果匹配失败, 则有gateway返回404信息
    *           #疑问: 这里配置的 uri 是固定,在当前这种情况其实可以没有有Eureka Server,后面会使用灵活方式
    *           #     配置,就会使用到Eureka Server
    *           uri: http://localhost:10000
    *           predicates: #断言,可以有多种形式
    *             - Path=/member/get/**
    */
   @Bean
   public RouteLocator myRouteLocator04(RouteLocatorBuilder routeLocatorBuilder) {

       RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

       //方法写完
       //梳理
       //1. 下面的方法我们分别指定了id , uri 和path
       //2. Function<PredicateSpec, Route.AsyncBuilder> fn
       //(1) 是一个函数式接口
       //(2) 接收的类型是 PredicateSpec ,返回的类型是 Route.AsyncBuilder
       //(3) r -> r.path("/member/get/**")
       //                .uri("http://localhost:10000") 就是lambda表达式
       //(4) 一会还要用代码进行说明-先使用-再理解
       //3. 小伙伴们可以理解这是一个规定写法

       return routes.route("member_route04", r -> r.path("/member/get/**")
               .uri("http://localhost:10000"))
               .build();


   }

   @Bean
   public RouteLocator myRouteLocator05(RouteLocatorBuilder routeLocatorBuilder) {

       RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

       return routes.route("member_route05", r -> r.path("/member/save")
               .uri("http://localhost:10000"))
               .build();

   }
}

测试

1 启动e-commerce-eureka-server-9001

2 启动member-service-provider-10000

3 启动e-commerce-gateway-20000

4 浏览器:(通过网关访问) http://localhost:20000/member/get/1

结果和前面的一样这里就不再展示了

方别忘了,将代码恢复成yml 配置

动态路由

示意图 

代码实现

1. 修改e-commerce-gateway-20000 的application.yml

spring:
  application:
    name: e-commerce-gateway
  cloud:
    gateway:
      routes: #配置路由,可以配置多个路由 List<RouteDefinition> routes
        - id: member_route01 #路由的id, 程序员自己配置,要求唯一
          #gateway 最终访问的url 是 url=uri+Path
          #匹配后提供服务的路由地址: 也可以是外网 http://www.baidu.com
          #比如: 客户端/浏览器请求 url http://localhost:20000/member/get/1
          #如果根据Path匹配成功 最终访问的url/转发url 就是 url=http://localhost:10000/member/get/1
          #如果匹配失败, 则有gateway返回404信息
          #     配置,就会使用到Eureka Server
          #解读
          #1. lb: 协议名 , member-service-provider 注册到eureka server 服务名(小写)
          #2. 默认情况下,负载均衡算法是轮询
          uri: lb://member-service-provider
          predicates: #断言,可以有多种形式
            - Path=/member/get/**

        - id: member_route02 #路由的id, 程序员自己配置,要求唯一
          uri: lb://member-service-provider
          predicates: #断言,可以有多种形式
            #这时如果客户端/浏览器 访问gateway 的url http://localhost:20000/member/save
            #匹配Path成功 最终访问的url 就是 http://localhost:10000/member/save
            - Path=/member/save

测试

1 启动e-commerce-eureka-server-9001

2 启动member-service-provider-10000

3 启动e-commerce-gateway-20000

4 浏览器:(通过网关访问) http://localhost:20000/member/get/1

Postman 测试添加(走网关, 前面演示过了这里就不再展示了) 

注意事项和细节

1 配置好动态路由后Gateway 会根据注册中心上微服务名,为请求创建动态路由,实现动态路由功能

2 使用的lb 协议支持负载均衡-轮询算法

3 配置自己的负载均衡算法, 测试完毕恢复成原来的轮询算法

代码

/**
* RibbonRule: 配置类-配置自己的负载均衡算法
*/
@Configuration
public class RibbonRule {

   //配置注入自己的负载均衡算法
   @Bean
   public IRule myRibbonRule() {
       //这里老师返回的是RandomRule,当然小伙伴也可以自己指定
       return new RandomRule();
   }
}

Predicate/断言

基本介绍

一句话: Predicate 就是一组匹配规则,当请求匹配成功,就执行对应的Route, 匹配失败,放弃处理/转发

Route Predicate Factories

- 文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读

1. Spring Cloud Gateway包括许多内置的Route Predicate工厂, 所有这些Predicate都与HTTP请求的不同属性匹配, 可以组合使用.

2. Spring Cloud Gateway 创建Route 对象时,使用RoutePredicateFactory 创建Predicate对象,Predicate 对象可以赋值给Route。

3. 所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合

Route Predicate 实例

After Route Predicate

需求: 只有2022-11-18 12:35:50 之后的请求才进行匹配/转发, 不满足该条件的,不处理

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

2. 修改e-commerce-gateway-20000 的application.yml

注意这里只展示需要修改的地方了全部配置上面有 

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]

 3. 如何获取时间格式, 创建一个测试类,来获取当前时间,再根据需要修改

springcloud/T2.java

public class T2 {
    public static void main(String[] args) {
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);
    }
}

测试

启动e-commerce-eureka-server-9001
启动member-service-provider-10000/10002
启动e-commerce-gateway-20000
浏览器:(通过网关访问) http://localhost:20000/member/get/1

Before Route Predicate

需求: 只有2022-11-18 12:35:50 之前的请求才进行匹配/转发, 不满足该条件的,不处理

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

 2. 修改e-commerce-gateway-20000 的application.yml

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
#- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
- Before=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]

测试步骤和前面的一样这个就不再冲重复了

Between Route Predicate

需求: 只有2020-11-18 12:35:50 和2022-11-18 12:35:50 之间的请求才进行匹配/转发, 不满足该条件的,不处理

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

2. 修改e-commerce-gateway-20000 的application.yml

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
#- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
#- Before=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
-
Between=2020-11-18T12:35:50.387+08:00[Asia/Shanghai],2022-11-18T12:35:50.387+0
8:00[Asia/Shanghai]

 Cookie Route Predicate

需求: 请求带有cookie 键: user 值: nihao才匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

解读:
chocolate 是cookie 名字ch.p 是cookie 的值,是按照正则表达式来匹配的 

2. 修改e-commerce-gateway-20000 的application.yml

predicates:
- Path=/member/get/** #断言,路径相匹配的进行路由
#- After=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
#- Before=2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
#-Between=2020-11-18T12:35:50.387+08:00[Asia/Shanghai],2022-11-18T12:35:50.387+08:00[Asia/Shanghai]
- Cookie=user, nihao

这个有点特殊所以单独截图

 如果和前面的一样这里就不在展示了

Header Route Predicate

需求: 请求头Header 有X-Request-Id, 并且值hello 才匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/
html/#gateway-request-predicates-factories

解读: X-Request-Id 是header 的名称, \d+ 是一个正则表达式 

2. 修改e-commerce-gateway-20000 的application.yml

#- Cookie=key1, abc
- Header=X-Request-Id, hello

Host Route Predicate

需求: 请求Host 是**.wyxedu.** 才匹配/断言成功, 比如Host www.wyxedu.com 

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读: Host 可以有多个, 使用逗号间隔 

2. 修改e-commerce-gateway-20000 的application.yml

#- Header=X-Request-Id, hello
- Host=**.wyxedu.**

Method Route Predicate

 需求: 请求是Get 方式才匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读: 请求方式可以有多个, 使用逗号间隔 

2. 修改e-commerce-gateway-20000 的application.yml

#- Host=**.wyxedu.**
- Method=GET

 注意 我们设置的GET方式 所以会报错

Path Route Predicate

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

解读: Path 可以有多个, 使用逗号间隔 

Query Route Predicate

需求: 请求有参数email ,并且满足电子邮件的基本格式, 才能匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

 解读: red 是参数名gree. 是值, 支持正则表达式

2. 修改e-commerce-gateway-20000 的application.yml

#- Host=**.wyxedu.**
#- Method=GET
- Query=email, [\w-]+@([a-zA-Z]+\.)+[a-zA-Z]+

注意启动哪些服务都是一样的

这里再提醒一下

启动e-commerce-eureka-server-9001
启动member-service-provider-10000/10002
启动e-commerce-gateway-20000 

 RemoteAddr Route Predicate

需求: 请求的IP 是127.0.0.1, 才能匹配/断言成功

1. 参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

2. 修改e-commerce-gateway-20000 的application.yml

#提示:通过http://127.0.0.1:20000/member/get/1 ,可以看到效果.
- RemoteAddr=127.0.0.1

 

注意因为本机默认ip是127.0.0.1 所以可以不用直接指定 但是如果是其他的ip就需要指定

如请求的是192.168.1.2 如果想要看到效果的话就 http://192.168.1.2:20000/member/get/1

测试完毕,记得代码恢复到测试前 

 Filter/过滤器

基本介绍

1. 文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories

解读

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应
Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生 

类型

1 GatewayFilter

2 GlobalFilter 

文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#global-filters

GatewayFilter 使用

1 开发直接使用GatewayFilter 较少,一般是自定义过滤器
2 参考实例

 参考文档地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#the-addrequestheader-gatewayfilter-factory 

2. 修改e-commerce-gateway-20000 的application.yml

            #- RemoteAddr=127.0.0.1
          filters:
            - AddRequestParameter=color, blue#过滤器工厂会在匹配的请求头加上一对请求头,名称为color 值为blue
            - AddRequestParameter=age, 18#过滤器工厂会在匹配的请求头加上一对请求头,名称为age 值为18

3. 验证

修改member-service-provider-10000\src\main\java\com\springcloud\controller\MemberController.java

@GetMapping("/member/get/{id}")
    public Result getMemberById(@PathVariable("id") Long id, HttpServletRequest request) {

        String color = request.getParameter("color");
        String address = request.getParameter("age");

        Member member = memberService.queryMemberById(id);

        //使用Result把查询到的结果返回
        if (member != null) {
            return Result.success("查询会员成功 member-service-provider-10000 " + color + "-" + age, member);
          
        } else {
            return Result.error("402", "ID= " + id + "不存在");
        }

    }

自定义GlobalFilter

1 需求分析/图解
1. 自定义全局GlobalFilter 过滤器
2. 如果请求参数user=wyxdu, pwd=123456 则放行, 否则不能通过验证 

代码实现

1. 在e-commerce-gateway-20000 创建com/springcloud/filter/CustomGateWayFilter.java

@Component
public class CustomGateWayFilter implements GlobalFilter, Ordered {

   //filter是核心的方法,将我们的过滤的业务,写在该方法中
   @Override
   public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       System.out.println("------CustomGateWayFilter------");
       //先获取到对应的参数值
       //比如 http://localhost:20000/member/get/1?user=wyxedu&pwd=123456
       String user =
               exchange.getRequest().getQueryParams().getFirst("user");
       String pwd = exchange.getRequest().getQueryParams().getFirst("pwd");
       if(!("wyxdu".equals(user) && "123456".equals(pwd))) {//如果不满足条件
           System.out.println("-----非法用户-----");
           exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//回应
           return exchange.getResponse().setComplete();
       }
       //验证通过, 放行
       return chain.filter(exchange);
   }


   //order 表示过滤器执行的顺序, 数字越小, 优先级越高
   @Override
   public int getOrder() {
       return 0;
   }
}

测试

1 启动e-commerce-eureka-server-9001
2 启动member-service-provider-10000/10002
3 启动e-commerce-gateway-20000
4 浏览器:(通过网关访问) http://localhost:20000/member/get/1?user=wyxdu&pwd=123456

如果不通过就 显示这个

 

 测试完毕,记得代码恢复到测试前

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/625233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tamper脚本编写与mitmdump

tamper脚本编写与mitmdump 0x01 前提 ​ 注入点在登录框处&#xff0c;但是目标每次都会先校验验证码&#xff0c;而验证码会在返回包中以json格式出现。 0x02 编写tamper脚本 由于目标的验证码在response中回显出来了&#xff0c;所以我们可以利用tamper脚本去读取验证码&a…

Python:SVOREX

公式看懂了就写导数。写完导数撸码 Car数据集上对比: 在Car数据集上,SVOREX稍微胜出。 """ SVOREX author: Daniel He at CQUPT 2023-06-08 """ import xlwt import xlrd import numpy as np import pandas as pd import matplotlib.pylab a…

17.16按摩师

目录 一、题目 二、分析代码 一、题目 面试题 17.16. 按摩师 - 力扣&#xff08;LeetCode&#xff09; 二、分析代码 class Solution { public:int massage(vector<int>& nums) {int nnums.size();// vector<int>dp(n,0);// if(n<0)// return 0;// if(n1…

Docker部署ssh连接工具webssh2

Docker部署ssh连接工具webssh2 一、检查系统版本二、检查docker状态三、下载webssh2镜像四、创建webssh2容器1.创建webssh2容器2.查看webssh2状态3.查看容器运行日志 五、访问webssh21. 访问webssh22. 远程连接服务器3. 文件管理 一、检查系统版本 检查操作系统版本 [rootserve…

Python对普通文件的操作

目录 1. 常用函数语法 1.1. open_打开文件 1.2. read_读取文件 1.3. readlines_读取文件 1.4. csv.reader_读取csv文件 1.5. write_写入内容 2. 操作普通文件 2.1. 读取内容 ① 按大小读取 ② 按行数读取 ③ 按列数读取 ④ 读取大文件 ⑤ 条件过滤 2.2. 写入内容…

一文详解!JMeter该如何并发测试和持续性压测?

目录 前言&#xff1a; 概念 并发测试 持续性压测 查看报告 总结 试试其他 API 工具 知识扩展&#xff1a; 前言&#xff1a; JMeter 是一个 Java 编写的开源负载测试工具&#xff0c;基于模拟用户、线程和请求&#xff0c;结合测试计划和策略&#xff0c;可以模拟真实…

和托托一起学计算机图形学(一)-初识计算机图形学

文章目录 初识计算机图形学一、计算机科学与视觉信息处理二、计算机图形学的应用三、总结 数字图像基础一、像素二、RGB和CMY颜色模型三、颜色编码四、查色表五、图像文件六、总结 初识计算机图形学 一、计算机科学与视觉信息处理 计算机图形学&#xff1a;建模&#xff08;建…

Kafka-Eagle安装及连接成功web端登陆不了问题解决

kafka自身并没有集成监控管理系统&#xff0c;因此对kafka的监控管理比较不便&#xff0c;好在有大量的第三方监控管理系统来使用&#xff0c;常见的有&#xff1a; Kafka EagleKafkaOffsetMonitorKafka Manager&#xff08;雅虎开源的Kafka集群管理器&#xff09;Kafka Web C…

1.7 基于XML配置方式使用Spring MVC

一、基于XML配置与注解的方式使用Spring MVC 1、创建Maven项目 Maven项目 - SpringMvcDemo01 单击【Finish】按钮 2、添加相关依赖 在pom.xml文件里添加支持Spring MVC的相关依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmln…

excel学习--开始界面控制台讲解

1、部分基础控制台讲解 上面的那行表示垂直居中 下面的那行表示水平居中 上面设置表格内容的表现方向 下面设置表格内容的缩进量 合并单元格的两种主要方式即左图所示&#xff0c;一种是跨越合并&#xff0c;另一种是合并单元格&#xff0c;跨越合并只能进行列合并&#xff0c…

09 - Linux进程层次分析

---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;Linux系统编程训练营 - 目录 文章目录 1. 详解Linux进程组1.1 Linux进程组1.2 进程组示例程序1.3 编程实验&#xff1a;Linux进程组1.4 深入理解进程组1.4.1 进程组标识设置技巧…

【算法题解】35. 两两交换链表中的节点

这是一道 中等难度 的题 https://leetcode.cn/problems/swap-nodes-in-pairs/ 题目 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff…

LVS负载均衡群集及VS/NAT部署

一、企业群集应用概述 1.群集的含义 群集&#xff08;Cluster&#xff09;&#xff0c;又称集群。由多台主机构成&#xff0c;但对外只表现为一个整体&#xff0c;只提供一个访问入口&#xff08;域名或IP地址&#xff09;&#xff0c;相当于一台大型计算机。 但是在互联网应…

htmlCSS-----元素类型

目录 前言&#xff1a; 元素类型 1.块级元素 2. 行内元素 3. 行内块元素 前言&#xff1a; 今天我们就学习CSS中的元素的类型&#xff0c;了解网页元素类型的相关性质&#xff0c;有助于我们去对网页进行排版处理。下面就一起去看看吧。 元素类型 常见元素类型有&#xff…

又壕又实惠的 AI 训练来了,Hugging Face 第一的 LLM 大模型 Falcon 40B 纳入亚马逊云科技服务

出品 | CSDN 云计算 2023 年&#xff0c;几乎是 AI 爆炸式发展的一年。各类大模型接踵而至&#xff0c;全行业都将 AIGC 融入生产流程&#xff0c;以提升效率。最近&#xff0c;阿联酋首都阿布扎比的科研中心 TII&#xff08;Technology Innovation Institute&#xff09;拥有 …

制氧机语音芯片新方案,高品质低功耗NV040C语音IC

在医疗设备行业中&#xff0c;制氧机是一种常见的设备&#xff0c;尤其在之前疫情期间&#xff0c;制氧机甚至成为了医院中不可或缺的设备之一。而在制氧机中加入语音芯片的语音方案&#xff0c;则可以进一步提高其人机交互的体验&#xff0c;增强其功能和可靠性。在制氧机中&a…

超超超详细C++入门总结

C入门知识总结 1.什么是C2. C关键字(C98)3.命名空间3.1命名空间定义1.命名空间的普通定义2.命名空间的嵌套定义3.同一个工程中允许存在多个相同名称的命名空间&#xff0c;编译器最后会合成同一个命名空间 3.2命名空间的使用1.加命名空间名称以及作用域限定符2.使用using将命名…

Flume事务

Flume事务 在Flume中一共有两个事务 Put事务&#xff1a;在Source组件和Channel组件之间&#xff0c;保证Source组件到Channel组件之间数据传递的可靠性。 take事务&#xff1a;在Channel组件和Sink组件之间&#xff0c;保证channel组件到Sink组件之间数据传输的可靠性。Put事务…

算法拾遗三十二bfprt算法,蓄水池算法

算法拾遗三十二bfprt算法&#xff0c;蓄水池算法 在无序数组中求第k小的数快排解法bfprt解法 练习题目蓄水池算法bfprt 应用 在无序数组中求第k小的数 快排解法 // 改写快排&#xff0c;时间复杂度O(N)// k > 1public static int minKth2(int[] array, int k) {int[] arr …

HNU计算机图形学-作业一

任务一&#xff1a;创建交互式三维场景 前言 完整工程文件 具体运行环境配置看这个栏目的第一篇文章 专选课计算机图形学的第一次作业&#xff0c;老师是第一次给本科生上课&#xff0c;用的作业是香港中文大学的计算机图形学的作业内容&#xff08;老师就是这个学校毕业&a…