分布式组件的全域认识和操作--gateway

我们对gateway这个技术栈,产生什么样的认识,才算真
正的理解,会使用gateway。

构建与注册层

1.如何搭建一个gateway项目,并且注册到gateway里面

应用与实践层

2.深刻理解gateway提供了哪些逻辑功能和机制。

要真正理解和使用Gateway技术栈,需要从架构认知、核心机制、实践应用三个维度建立系统性理解。让我为你构建一个完整的Gateway知识体系:

一、构建与注册层:从零搭建Gateway项目

1.1 基础搭建(最小实现)

// 1. 引入依赖(pom.xml)<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>// 2. 配置文件(application.yml) spring: cloud: gateway: routes:- id: user-service uri: lb://user-service predicates:-Path=/api/user/** filters: - StripPrefix=1 // 3. 启动类 @SpringBootApplication public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } } 

1.2 服务注册与发现

// 集成Nacos注册中心<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>// 配置Nacos spring: cloud: nacos: discovery: server-addr:127.0.0.1:8848 gateway: discovery: locator: enabled:true # 开启服务发现 lower-case-service-id:true

二、应用与实践层:Gateway核心机制深度理解

2.1 核心组件认知框架

请求流程: 客户端 → HandlerMapping → RouteLocator → Predicate → Filter → 目标服务 关键组件: - Route(路由):网关的基本构建块 - Predicate(断言):匹配条件 - Filter(过滤器):请求/响应处理 - HandlerMapping:路由匹配器 

2.2 七大核心机制详解

1️⃣ 路由机制(Route)
// 动态路由配置@BeanpublicRouteLocatorcustomRouteLocator(RouteLocatorBuilder builder){return builder.routes().route("order-service", r -> r.path("/api/order/**").filters(f -> f.stripPrefix(1)).uri("lb://order-service")).build();}

理解要点:

  • 路由是Gateway的核心,定义了请求转发规则
  • 支持静态配置和动态编程两种方式
  • 每个路由包含ID、目标URI、断言集合、过滤器集合
2️⃣ 断言机制(Predicate)
// 多条件组合断言 spring: cloud: gateway: routes:- id: complex-route uri: lb://service predicates:-Path=/api/** - Method=GET - Header=X-Request-Id, \d+ - Query=token, \w+ - After=2024-01-01T00:00:00+08:00 

理解要点:

  • 断言是路由匹配的条件判断器
  • 支持11种内置断言(Path、Method、Header、Query等)
  • 可组合使用,满足复杂路由需求
3️⃣ 过滤器机制(Filter)
// 自定义全局过滤器@ComponentpublicclassAuthFilterimplementsGlobalFilter,Ordered{@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){String token = exchange.getRequest().getHeaders().getFirst("Authorization");if(token ==null||!validateToken(token)){ exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}@OverridepublicintgetOrder(){return-100;// 优先级}}

理解要点:

  • 过滤器分为GatewayFilter(局部)和GlobalFilter(全局)
  • 执行顺序由Ordered接口的getOrder()方法决定
  • 可实现认证、限流、日志、修改请求/响应等
4️⃣ 负载均衡机制
// 自动集成Ribbon/LoadBalancer spring: cloud: gateway: routes:- id: service-route uri: lb://service-name # lb://前缀触发负载均衡 

理解要点:

  • 通过lb://前缀自动启用负载均衡
  • 支持轮询、随机、权重等多种策略
  • 与服务注册中心无缝集成
5️⃣ 限流机制(RateLimiter)
// 基于Redis的分布式限流 spring: cloud: gateway: routes:- id: rate-limit-route uri: lb://service filters:- name:RequestRateLimiter args: redis-rate-limiter.replenishRate:10 # 令牌桶填充速率 redis-rate-limiter.burstCapacity:20 # 令牌桶容量 key-resolver:"#{@userKeyResolver}" # 自定义key解析器 
@BeanKeyResolveruserKeyResolver(){return exchange ->Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));}
6️⃣ 熔断降级机制
// 集成Hystrix/Sentinel spring: cloud: gateway: routes:- id: circuit-breaker-route uri: lb://service filters:- name:Hystrix args: name: fallbackCommand fallbackUri: forward:/fallback 
7️⃣ 跨域处理机制
// 全局CORS配置@ConfigurationpublicclassCorsConfig{@BeanpublicCorsWebFiltercorsWebFilter(){CorsConfiguration config =newCorsConfiguration(); config.addAllowedOrigin("*"); config.addAllowedMethod("*"); config.addAllowedHeader("*"); config.setAllowCredentials(true);UrlBasedCorsConfigurationSource source =newUrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config);returnnewCorsWebFilter(source);}}

三、真正理解的标准

认知层面

  1. 架构理解:清楚Gateway在整个微服务架构中的定位和作用
  2. 组件关系:理解Route、Predicate、Filter三者的关系和执行流程
  3. 设计模式:掌握Gateway使用的责任链、工厂、策略等设计模式

机制层面

  1. 执行流程:能画出请求从进入到转发的完整流程图
  2. 扩展能力:知道如何自定义Predicate和Filter
  3. 异常处理:理解全局异常处理和降级策略

实践层面

  1. 配置能力:能根据业务需求灵活配置路由规则
  2. 问题排查:能通过日志和监控快速定位网关问题
  3. 性能优化:了解网关的性能瓶颈和优化方案

进阶理解

// 理解Gateway的底层原理// 1. 基于WebFlux的响应式编程模型// 2. Netty作为底层通信框架// 3. 异步非阻塞的IO处理// 4. 函数式编程的路由定义方式

四、实际应用场景示例

// 综合应用:API网关的完整配置 spring: cloud: gateway: # 全局过滤器配置 default-filters:-AddResponseHeader=X-Response-Default,Default-Value routes: # 用户服务路由 - id: user-service uri: lb://user-service predicates:-Path=/api/user/** filters: - StripPrefix=1 - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 100 redis-rate-limiter.burstCapacity: 200 # 订单服务路由(带认证) - id: order-service uri: lb://order-service predicates: - Path=/api/order/** filters: - StripPrefix=1 - name: Hystrix args: name: orderFallback fallbackUri: forward:/order/fallback # 静态资源路由 - id: static-resources uri: http://static.example.com predicates: - Path=/static/** 

总结:真正理解Gateway不仅仅是会配置,更要理解其设计理念、执行机制、扩展方式,能够在复杂场景下灵活运用,并具备问题排查和性能优化的能力。

这是一个非常深入的问题!让我从架构拓扑、性能原理、分发机制三个维度,系统地解析Gateway的内部构造。

一、Gateway内部拓扑构造

1.1 整体架构层次

┌─────────────────────────────────────────────────────────┐ │ 客户端请求层 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ Netty网络层 (EventLoop) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Acceptor │ │ EventLoop1 │ │ EventLoop2 │ │ │ │ 线程 │ │ 线程组 │ │ 线程组 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ WebFlux响应式处理层 (Reactor) │ │ ┌───────────────────────────────────────────────────┐ │ │ │ DispatcherHandler (请求分发器) │ │ │ │ ↓ │ │ │ │ RoutePredicateHandlerMapping (路由匹配) │ │ │ │ ↓ │ │ │ │ FilteringWebHandler (过滤器链) │ │ │ │ ↓ │ │ │ │ GatewayFilterChain (责任链) │ │ │ └───────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 路由与过滤器层 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Route │ │ Predicate │ │ Filter │ │ │ │ 路由定义 │ │ 断言匹配 │ │ 过滤器链 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 服务发现与负载均衡层 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Discovery │ │ LoadBalancer│ │ Connection │ │ │ │ 服务发现 │ │ 负载均衡 │ │ 连接池 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────┐ │ 目标服务层 │ └─────────────────────────────────────────────────────────┘ 

1.2 核心组件详解

// 1. DispatcherHandler - 请求入口分发器publicclassDispatcherHandlerimplementsWebHandler{privatefinalMap<String,HandlerMapping> handlerMappings;@OverridepublicMono<Void>handle(ServerWebExchange exchange){// 遍历所有HandlerMapping,找到匹配的处理器return handlerMappings.values().stream().filter(mapping -> mapping.matches(exchange)).findFirst().map(mapping -> mapping.getHandler(exchange)).orElse(Mono.error(newResponseStatusException(HttpStatus.NOT_FOUND))).flatMap(handler -> handler.handle(exchange));}}// 2. RoutePredicateHandlerMapping - 路由匹配器publicclassRoutePredicateHandlerMappingextendsAbstractHandlerMapping{@OverrideprotectedMono<?>getHandlerInternal(ServerWebExchange exchange){// 1. 获取所有路由Flux<Route> routes = routeLocator.getRoutes();// 2. 根据Predicate匹配路由return routes.filter(route ->{List<PredicateDefinition> predicates = route.getPredicates();return predicates.stream().allMatch(predicate -> predicate.apply(exchange));}).next()// 返回第一个匹配的路由.map(route ->{ exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, route);return webHandler;// 返回FilteringWebHandler});}}// 3. FilteringWebHandler - 过滤器链处理器publicclassFilteringWebHandlerimplementsWebHandler{@OverridepublicMono<Void>handle(ServerWebExchange exchange){Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);// 1. 获取路由的过滤器List<GatewayFilter> routeFilters = route.getFilters();// 2. 获取全局过滤器List<GlobalFilter> globalFilters =globalFilters();// 3. 合并并排序List<GatewayFilter> combined =combineFilters(routeFilters, globalFilters);// 4. 构建过滤器链GatewayFilterChain chain =newDefaultGatewayFilterChain(combined);// 5. 执行过滤器链return chain.filter(exchange);}}// 4. DefaultGatewayFilterChain - 责任链模式privatestaticclassDefaultGatewayFilterChainimplementsGatewayFilterChain{privatefinalint index;privatefinalList<GatewayFilter> filters;@OverridepublicMono<Void>filter(ServerWebExchange exchange){if(index < filters.size()){// 递归调用下一个过滤器GatewayFilter filter = filters.get(index);return filter.filter(exchange,this);}else{// 所有过滤器执行完毕,转发请求return((NettyRoutingFilter) filters.get(filters.size()-1)).route(exchange);}}}

二、为什么Gateway能承受大流量

2.1 响应式编程模型(Reactor Pattern)

// 传统阻塞IO vs 响应式非阻塞IO// 传统Servlet模型(阻塞)@WebServlet("/api")publicclassBlockingServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp){// 每个请求占用一个线程,直到IO完成String result = database.query();// 阻塞等待 resp.getWriter().write(result);}}// 问题:1000个并发请求 = 1000个线程 = 高内存消耗// Gateway响应式模型(非阻塞)@GetMapping("/api")publicMono<String>reactiveApi(){// 线程不等待,注册回调,IO完成后触发return database.queryAsync()// 返回Mono.map(result ->process(result));}// 优势:少量线程处理大量并发请求

2.2 Netty的事件驱动架构

// Netty线程模型 ┌─────────────────────────────────────────────────────┐ │ BossEventLoopGroup │ │ (1个线程,负责Accept连接) │ │ ┌───────────────────────────────────────────────┐ │ │ │ ServerSocketChannel → Accept → SocketChannel │ │ │ └───────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ WorkerEventLoopGroup │ │ (N个线程,负责IO读写) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐│ │ │ EventLoop│ │ EventLoop│ │ EventLoop│ │ EventLoop││ │ │ 线程1 │ │ 线程2 │ │ 线程3 │ │ 线程4 ││ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘│ │ ↓ ↓ ↓ ↓ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐│ │ │Channel1 │ │Channel2 │ │Channel3 │ │Channel4 ││ │ │Channel2 │ │Channel3 │ │Channel4 │ │Channel5 ││ │ │Channel3 │ │Channel4 │ │Channel5 │ │Channel6 ││ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘│ └─────────────────────────────────────────────────────┘ // 关键特性:// 1. 一个EventLoop绑定多个Channel(连接)// 2. 每个Channel的生命周期绑定到同一个EventLoop// 3. 无锁化设计,避免线程切换开销

2.3 线程模型对比

// 传统Tomcat线程模型 ┌─────────────────────────────────────────────────────┐ │ ThreadPool(200个线程) │ │ ┌─────┐ ┌─────┐ ┌─────┐ ... ┌─────┐ │ │ │Thread│ │Thread│ │Thread│ │Thread│ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ ↓ ↓ ↓ ↓ │ │ Request1Request2Request3Request200 │ │ (每个请求占用一个线程,直到完成) │ └─────────────────────────────────────────────────────┘ // 问题:线程上下文切换开销大,内存占用高// Gateway Netty线程模型 ┌─────────────────────────────────────────────────────┐ │ EventLoopGroup(CPU核心数 *2) │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ EventLoop1 │ │ EventLoop2 │ │ │ │ (处理1000+ │ │ (处理1000+ │ │ │ │ 连接) │ │ 连接) │ │ │ └─────────────┘ └─────────────┘ │ │ ↓ ↓ │ │ Channel1-1000Channel1001-2000 │ └─────────────────────────────────────────────────────┘ // 优势:少量线程处理海量连接,无阻塞等待

2.4 内存管理优化

// Netty的内存池化技术(PooledByteBufAllocator)// 传统方式:每次分配新内存byte[] buffer1 =newbyte[1024];// 分配// 使用... buffer1 =null;// 释放,等待GC// Netty内存池:复用内存块PooledByteBufAllocator allocator =PooledByteBufAllocator.DEFAULT;ByteBuf buffer = allocator.buffer(1024);// 从池中获取// 使用... buffer.release();// 归还到池中,可复用// 优势:// 1. 减少内存分配/释放开销// 2. 降低GC压力// 3. 避免内存碎片

2.5 连接复用与连接池

// HTTP连接池配置 spring: cloud: gateway: httpclient: pool: type: ELASTIC # 弹性连接池 max-connections:1000 # 最大连接数 acquire-timeout:45000 # 获取连接超时 // 连接复用机制 ┌─────────────────────────────────────────────────────┐ │ ConnectionPool(连接池) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Conn1 │ │ Conn2 │ │ Conn3 │ │ │ │ (复用) │ │ (复用) │ │ (复用) │ │ │ └─────────┘ └─────────┘ └─────────┘ │ └─────────────────────────────────────────────────────┘ ↓ ↓ ↓ Service1Service2Service3// 优势:// 1. 避免频繁建立/断开TCP连接// 2. 减少TCP握手开销// 3. 提高请求响应速度

三、请求分发机制

3.1 路由匹配算法

// 路由匹配流程publicclassRoutePredicateHandlerMapping{publicMono<Route>getRoute(ServerWebExchange exchange){return routeLocator.getRoutes().filter(route ->{// 1. Path匹配(AntPathMatcher)if(route.getPath()!=null){AntPathMatcher matcher =newAntPathMatcher();if(!matcher.match(route.getPath(), exchange.getRequest().getPath().value())){returnfalse;}}// 2. Method匹配if(route.getMethod()!=null){if(!route.getMethod().equals(exchange.getRequest().getMethod())){returnfalse;}}// 3. Header匹配if(route.getHeaders()!=null){for(Map.Entry<String,String> header : route.getHeaders().entrySet()){String value = exchange.getRequest().getHeaders().getFirst(header.getKey());if(value ==null||!value.matches(header.getValue())){returnfalse;}}}// 4. Query匹配// 5. Cookie匹配// 6. 其他Predicate...returntrue;}).next();// 返回第一个匹配的路由}}// 性能优化:路由缓存privatefinalMap<String,Route> routeCache =newConcurrentHashMap<>();publicMono<Route>getCachedRoute(String path){returnMono.justOrEmpty(routeCache.get(path)).switchIfEmpty(getRouteFromLocator(path).doOnNext(route -> routeCache.put(path, route)));}

3.2 负载均衡策略

// LoadBalancerClientFilter - 负载均衡过滤器publicclassLoadBalancerClientFilterimplementsGlobalFilter{@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);if(url !=null&&"lb".equals(url.getScheme())){// 1. 解析服务名String serviceId = url.getHost();// 2. 获取服务实例列表ServiceInstance instance = loadBalancer.choose(serviceId);// 3. 构建实际请求URLURI uri =reconstructURI(instance, url); exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri);}return chain.filter(exchange);}}// 负载均衡算法实现publicclassRoundRobinLoadBalancerimplementsReactorServiceInstanceLoadBalancer{privatefinalAtomicInteger position =newAtomicInteger();@OverridepublicMono<ServiceInstance>choose(Request request){List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);if(instances.isEmpty()){returnMono.empty();}// 轮询算法int pos =Math.abs(position.incrementAndGet()% instances.size());returnMono.just(instances.get(pos));}}// 权重负载均衡publicclassWeightedLoadBalancer{publicServiceInstancechooseWeighted(List<ServiceInstance> instances){// 计算总权重int totalWeight = instances.stream().mapToInt(i -> i.getMetadata().getOrDefault("weight","1")).mapToInt(Integer::parseInt).sum();// 随机选择int random =ThreadLocalRandom.current().nextInt(totalWeight);// 根据权重分配int current =0;for(ServiceInstance instance : instances){ current +=Integer.parseInt(instance.getMetadata().get("weight"));if(random < current){return instance;}}return instances.get(0);}}

3.3 动态路由更新

// 基于Nacos的动态路由@ComponentpublicclassNacosRouteDefinitionRepositoryimplementsRouteDefinitionRepository{@AutowiredprivateConfigService configService;// 监听Nacos配置变化@PostConstructpublicvoidinit()throwsNacosException{ configService.addListener("gateway-routes","DEFAULT_GROUP",newListener(){@OverridepublicvoidreceiveConfigInfo(String configInfo){// 解析配置List<RouteDefinition> routes =parseRoutes(configInfo);// 更新路由 routes.forEach(route ->{ routeDefinitionWriter.save(Mono.just(route)).subscribe();});}});}@OverridepublicFlux<RouteDefinition>getRouteDefinitions(){// 从Nacos获取路由配置String config = configService.getConfig("gateway-routes","DEFAULT_GROUP",5000);List<RouteDefinition> routes =parseRoutes(config);returnFlux.fromIterable(routes);}}// 路由热更新流程 ┌─────────────────────────────────────────────────────┐ │ 1.Nacos配置变更 │ │ ↓ │ │ 2. 监听器收到通知 │ │ ↓ │ │ 3. 解析新的路由配置 │ │ ↓ │ │ 4. 调用RouteDefinitionWriter保存 │ │ ↓ │ │ 5.CachingRouteLocator清除缓存 │ │ ↓ │ │ 6. 新路由生效(无需重启) │ └─────────────────────────────────────────────────────┘ 

四、性能数据对比

// 理论性能对比// 传统Tomcat (Servlet)// 线程数:200// 每个线程处理时间:50ms// 理论QPS = 200 / 0.05 = 4000// Gateway (Netty + WebFlux)// EventLoop线程数:8 (4核CPU * 2)// 每个请求处理时间:50ms(非阻塞)// 理论QPS = 8 * (1000/50) * 并发系数 ≈ 80000+// 实际测试数据(仅供参考)// 场景:简单路由转发// 硬件:4核8G// // Tomcat: ~5000 QPS, 延迟 20ms// Gateway: ~30000 QPS, 延迟 5ms

五、总结:Gateway高性能的核心原理

特性传统ServletGateway (WebFlux + Netty)
编程模型阻塞IO非阻塞响应式
线程模型每请求一线程少量EventLoop处理海量连接
内存管理频繁分配/释放内存池复用
连接管理短连接连接池复用
扩展性垂直扩展水平扩展

核心优势:

  1. 事件驱动:无阻塞等待,线程利用率高
  2. 内存池化:减少GC压力,提高性能
  3. 连接复用:降低TCP握手开销
  4. 响应式流:背压机制,防止系统过载

这就是为什么Gateway能够承受大流量的根本原因!

Read more

2026 年 windows Python 最新下载安装教程,附详细图文,亲测可用

📖 前言 想学编程?Python 是个好选择。语法简单、上手快,数据分析和 AI 都能干。 但很多人第一步就卡住了——装软件。我当年第一次装 Python 也在这个坑里折腾了半天,后来才发现其实挺简单的,只是没人告诉我哪些选项该勾、哪些不该勾。 今天就把这个过程写清楚,每一步都有图,跟着做就行。 📝 开始装 第一步:下载安装包 1.1 去官网下 打开浏览器,网盘链接:https://pan.quark.cn/s/7186f4aa4c10 进去后能看到一个黄色大按钮,上面写着最新的版本号(目前是 3.13.x)。点它就开始下载。 1.2 选对版本 官网一般会自动识别你的系统,推荐对应的版本。你也可以手动选: * Windows installer (64-bit)

By Ne0inhk
用 Python 调用 Bright Data MCP Server:在 VS Code 中实现实时网页数据抓取

用 Python 调用 Bright Data MCP Server:在 VS Code 中实现实时网页数据抓取

用 Python 调用 Bright Data MCP Server:在 VS Code 中实现实时网页数据抓取,本文介绍了Bright Data的Web MCP Server,这是一款能实现实时、结构化网页数据访问的API,适用于AI应用等场景。其支持静态与动态网页,前3个月每月提供5000次免费请求,有远程托管和本地部署两种方式。文章以在VS Code中用Python调用其API抓取Google搜索结果为例,详解了准备工作、代码编写、参数说明等实战流程,还提及该工具免维护代理池等技术亮点及使用限制。 一、引言:为什么AI时代需要高效的网页数据访问工具? 在大语言模型(LLM)和智能代理(Agent)快速发展的今天,"实时性"成为AI应用落地的关键瓶颈。想象一下:当你的AI助手需要回答"今天上海的天气预警"或"某款产品的最新用户评价"时,它必须依赖实时网页数据才能给出准确答案—

By Ne0inhk
LeetCode Hot100 刷题路线(Python版)

LeetCode Hot100 刷题路线(Python版)

目录 1. LeetCode Hot100 刷题笔记(1)—— 哈希、双指针、滑动窗口-ZEEKLOG博客 2. LeetCode Hot100 刷题笔记(2)—— 子串、普通数组、矩阵-ZEEKLOG博客 3. LeetCode Hot100 刷题笔记(3)—— 链表-ZEEKLOG博客 4. LeetCode Hot100 刷题笔记(4)—— 二叉树、图论-ZEEKLOG博客 5. LeetCode Hot100 刷题笔记(5)—— 回溯-ZEEKLOG博客 6. LeetCode Hot100 刷题笔记(6)—— 栈、堆-ZEEKLOG博客 7. LeetCode Hot100 刷题笔记(7)—— 贪心-ZEEKLOG博客 8.

By Ne0inhk