网页在线制作网站3d房子模型设计软件

news/2025/10/2 15:33:56/文章来源:
网页在线制作网站,3d房子模型设计软件,企业网站的切片怎么做,漳州网站开发制作大家好#xff0c;前面我已经剖析了OpenFeign的动态代理生成原理和Ribbon的运行原理#xff0c;这篇文章来继续剖析SpringCloud组件原理#xff0c;来看一看OpenFeign是如何基于Ribbon来实现负载均衡的#xff0c;两组件是如何协同工作的。 一、Feign动态代理调用实现rpc流…大家好前面我已经剖析了OpenFeign的动态代理生成原理和Ribbon的运行原理这篇文章来继续剖析SpringCloud组件原理来看一看OpenFeign是如何基于Ribbon来实现负载均衡的两组件是如何协同工作的。 一、Feign动态代理调用实现rpc流程分析 通过Feign客户端接口的动态代理生成原理讲解我们可以清楚的知道Feign客户端接口的动态代理生成是基于JDK的动态代理来实现的那么在所有的方法调用的时候最终都会走InvocationHandler接口的实现默认就是ReflectiveFeign.FeignInvocationHandler那我们接下来就来看看FeignInvocationHandler是如何实现rpc调用的。 FeignInvocationHandler对于invoke方法的实现。 private final MapMethod, MethodHandler dispatch; Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (equals.equals(method.getName())) { try { Object otherHandler args.length 0 args[0] ! null ? Proxy.getInvocationHandler(args[0]) : null; return equals(otherHandler); } catch (IllegalArgumentException e) { return false; } } else if (hashCode.equals(method.getName())) { return hashCode(); } else if (toString.equals(method.getName())) { return toString(); }return dispatch.get(method).invoke(args); } 前几个if判断很简单就是判断是不是调用的方法是不是equalshashCodetoString因为这些方法的调是不需要走rpc调用的。 接下就是从dispatch获取要调用的方法对应的MethodHandler然后调用MethodHandler的invoke方法。那MethodHandler是什么时候生成的呢MethodHandler是在构建动态代理的时候生成的不清楚的同学可以翻一下OpenFeign那篇文章最后关于生成动态代理的那部分源码。那MethodHandler作用是什么呢你可以理解为最终rpc的调用都是基于这个MethodHandler来实现的每个方法都有对应MethodHandler来实现rpc调用接下来我们就来看一下MethodHandler的invoke方法的实现。 MethodHandler是个接口有两个实现类一个是DefaultMethodHandler这个是处理接口中的默认方法的另一个是SynchronousMethodHandler这个是实现rpc调用的方法。接下来我们就看看SynchronousMethodHandler关于invoke方法的实现。 Override public Object invoke(Object[] argv) throws Throwable { RequestTemplate template buildTemplateFromArgs.create(argv); Options options findOptions(argv); Retryer retryer this.retryer.clone(); while (true) { try { return executeAndDecode(template, options); } catch (RetryableException e) { try { retryer.continueOrPropagate(e); } catch (RetryableException th) { Throwable cause th.getCause(); if (propagationPolicy UNWRAP cause ! null) { throw cause; } else { throw th; } } if (logLevel ! Logger.Level.NONE) { logger.logRetry(metadata.configKey(), logLevel); } continue; } } } 第一行通过方法的参数构建了一个RequestTemplateRequestTemplate可以看成是组装http请求所需各种参数的封装比如什么情头body之类的都放在这里面。 第二行 Options options findOptions(argv); 这个很有意思Options主要是封装了发送请求是连接超时时间和读超时时间的配置findOptions(argv)也就是先从参数里面找有没有Options没有就返回构造SynchronousMethodHandler的入参时的Options也就是说连接超时时间和读超时时间可以从方法入参来传入不过一般没有人这么玩。 第三行就是搞一个重试的组件是可以实现重试的一般不设置。 然后执行到executeAndDecode(template, options)进入这个方法 Object executeAndDecode(RequestTemplate template, Options options) throws Throwable { Request request targetRequest(template);if (logLevel ! Logger.Level.NONE) { logger.logRequest(metadata.configKey(), logLevel, request); }Response response; long start System.nanoTime(); try { response client.execute(request, options); } catch (IOException e) { if (logLevel ! Logger.Level.NONE) { logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start)); } throw errorExecuting(request, e); } long elapsedTime TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);boolean shouldClose true; try { if (logLevel ! Logger.Level.NONE) { response logger.logAndRebufferResponse(metadata.configKey(), logLevel, response, elapsedTime); } if (Response.class metadata.returnType()) { if (response.body() null) { return response; } if (response.body().length() null || response.body().length() MAX_RESPONSE_BUFFER_SIZE) { shouldClose false; return response; } // Ensure the response body is disconnected byte[] bodyData Util.toByteArray(response.body().asInputStream()); return response.toBuilder().body(bodyData).build(); } if (response.status() 200 response.status() 300) { if (void.class metadata.returnType()) { return null; } else { Object result decode(response); shouldClose closeAfterDecode; return result; } } else if (decode404 response.status() 404 void.class ! metadata.returnType()) { Object result decode(response); shouldClose closeAfterDecode; return result; } else { throw errorDecoder.decode(metadata.configKey(), response); } } catch (IOException e) { if (logLevel ! Logger.Level.NONE) { logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime); } throw errorReading(request, response, e); } finally { if (shouldClose) { ensureClosed(response.body()); } } } 首先调用了targetRequest方法贴出源码 Request targetRequest(RequestTemplate template) { for (RequestInterceptor interceptor : requestInterceptors) { interceptor.apply(template); } return target.apply(template); } 这个方法会遍历所有的拦截器RequestInterceptor这是feign的一个扩展点也就说再发送请求前你仍然还有机会对请求的内容进行调整比如说加个请求头这也是很常见的一种方式在微服务之间鉴权的时候使用。RequestInterceptor是在构建Feign.Builder的时候传进来的Feign.Builder的组件都是通过ioc容器获取的组件又是通过配置类来的所以你需要的话就可以在配置类中声明RequestInterceptor对象。配置类有不同的优先级按照自己的需求可以在其中一个优先级使用不过一般这种通用的东西不是某个微服务特有的功能一般选择在springboot启动中的容器中配置。 执行完targetRequest回到executeAndDecode之后会构建出一个RequestRequest很好理解就是一个请求里面封装了http请求的东西。接下来就会调用Client的execute方法来执行请求拿到响应接下来就是基于处理这个响应将响应数据封装成需要返回的参数之后返回给调用方。 到这里我们已经分析出接口的动态代理是如何运行的。其实就是通过每个方法对应的MethodHandler来实现的MethodHandler主要就是拼接各种参数组装成一个请求随后交由Client接口的实现去发送请求。 二、LoadBalancerFeignClient 通过上面分析整个动态代理调用过程可以看出Client是发送http请求的关键类。那么Client是什么玩意?还记得我在关于OpenFeign动态代理生成的那篇文章中留下的一个疑问么当Feign客户端在构建动态代理的时候填充很多组件到Feign.Builder中其中有个组件就是Client的实现我们并没有在FeignClientsConfiguration配置类中找到关于Client的对象的声明。不过当时我就提到了这个组件的实现是要依赖负载均衡的也就是这个组件是Feign用来整合Ribbon的入口。 接下来我们就着重看一下Client的实现看看Feign是如何通过ribbon实现负载均衡的。 我们先来看一下Feign跟ribbon整合的配置类。 Import({ HttpClientFeignLoadBalancedConfiguration.class, OkHttpFeignLoadBalancedConfiguration.class, DefaultFeignLoadBalancedConfiguration.class })public class FeignRibbonClientAutoConfiguration {Bean Primary ConditionalOnMissingBean ConditionalOnMissingClass(org.springframework.retry.support.RetryTemplate) public CachingSpringLoadBalancerFactory cachingLBClientFactory( SpringClientFactory factory) { return new CachingSpringLoadBalancerFactory(factory); }Bean Primary ConditionalOnMissingBean ConditionalOnClass(name org.springframework.retry.support.RetryTemplate) public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory( SpringClientFactory factory, LoadBalancedRetryFactory retryFactory) { return new CachingSpringLoadBalancerFactory(factory, retryFactory); }Bean ConditionalOnMissingBean public Request.Options feignRequestOptions() { return LoadBalancerFeignClient.DEFAULT_OPTIONS; } } 我们来分析一下首先通过Impot注解导入了三个配置类。 HttpClientFeignLoadBalancedConfiguration基于HttpClient实现http调用的。 OkHttpFeignLoadBalancedConfiguration基于OkHttp实现http调用的。 DefaultFeignLoadBalancedConfiguration默认的也就是Feign原生的发送http的实现。 这里我们看一下DefaultFeignLoadBalancedConfiguration配置类因为默认就是这HttpClientFeignLoadBalancedConfiguration和OkHttpFeignLoadBalancedConfiguration都需要有引入HttpClient和OkHttp依赖才会有用 Configuration(proxyBeanMethods false)class DefaultFeignLoadBalancedConfiguration {Bean ConditionalOnMissingBean public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) { return new LoadBalancerFeignClient(new Client.Default(null, null), cachingFactory, clientFactory); } } 这个配置类很简单声明了LoadBalancerFeignClient到spring容器传入了三个参数一个Client的实现一个CachingSpringLoadBalancerFactory和一个SpringClientFactory。LoadBalancerFeignClient这个类实现了Client接口也就数说我们在构建Feign.Builder填充的就是这个对象也就是上面说feign的执行流程最后用来执行请求的Client的实现。 接下来我说一下入参的三个参数是什么意思。 Client.Default就是Feign自己实现的Client里面封装了真正发送http发送请求的功能LoadBalancerFeignClient虽然也实现了Client接口但是这个实现其实是为了整合Ribbon用的并没有发送http的功能所以需要有个可以发送http功能的实现。 CachingSpringLoadBalancerFactory后面会说这个类的作用 SpringClientFactory这个跟Feign里面的FeignContext的作用差不多用来实现配置隔离的当然这个也在关于Ribbon的那篇文章有剖析过。 其实大家可以自行去看OkHttpFeignLoadBalancedConfiguration和HttpClientFeignLoadBalancedConfiguration其实他们配置跟DefaultFeignLoadBalancedConfiguration是一样的声明的对象都是LoadBalancerFeignClient只不过将Client.Default换成了基于HttpClient和OkHttp的实现也就是发送http请求使用的工具不一样。 FeignRibbonClientAutoConfiguration除了导入配置类还声明了CachingSpringLoadBalancerFactory只不过一种是带基于spring实现的重试功能的一种是不带的主要看有没有引入spring重试功能的包所以上面构建LoadBalancerFeignClient注入的CachingSpringLoadBalancerFactory就是在这声明的。 这里就说完了Feign整合ribbon的配置类FeignRibbonClientAutoConfiguration我们也找到了构造Feign.Builder的实现LoadBalancerFeignClient接下来就来剖析LoadBalancerFeignClient的实现。 public class LoadBalancerFeignClient implements Client {static final Request.Options DEFAULT_OPTIONS new Request.Options();private final Client delegate;private CachingSpringLoadBalancerFactory lbClientFactory;private SpringClientFactory clientFactory;public LoadBalancerFeignClient(Client delegate, CachingSpringLoadBalancerFactory lbClientFactory, SpringClientFactory clientFactory) { this.delegate delegate; this.lbClientFactory lbClientFactory; this.clientFactory clientFactory; }static URI cleanUrl(String originalUrl, String host) { String newUrl originalUrl; if (originalUrl.startsWith(https://)) { newUrl originalUrl.substring(0, 8) originalUrl.substring(8 host.length()); } else if (originalUrl.startsWith(http)) { newUrl originalUrl.substring(0, 7) originalUrl.substring(7 host.length()); } StringBuffer buffer new StringBuffer(newUrl); if ((newUrl.startsWith(https://) newUrl.length() 8) || (newUrl.startsWith(http://) newUrl.length() 7)) { buffer.append(/); } return URI.create(buffer.toString()); }Override public Response execute(Request request, Request.Options options) throws IOException { try { URI asUri URI.create(request.url()); String clientName asUri.getHost(); URI uriWithoutHost cleanUrl(request.url(), clientName); FeignLoadBalancer.RibbonRequest ribbonRequest new FeignLoadBalancer.RibbonRequest( this.delegate, request, uriWithoutHost);IClientConfig requestConfig getClientConfig(options, clientName); return lbClient(clientName) .executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse(); } catch (ClientException e) { IOException io findIOException(e); if (io ! null) { throw io; } throw new RuntimeException(e); } }IClientConfig getClientConfig(Request.Options options, String clientName) { IClientConfig requestConfig; if (options DEFAULT_OPTIONS) { requestConfig this.clientFactory.getClientConfig(clientName); } else { requestConfig new FeignOptionsClientConfig(options); } return requestConfig; }protected IOException findIOException(Throwable t) { if (t null) { return null; } if (t instanceof IOException) { return (IOException) t; } return findIOException(t.getCause()); }public Client getDelegate() { return this.delegate; }private FeignLoadBalancer lbClient(String clientName) { return this.lbClientFactory.create(clientName); }static class FeignOptionsClientConfig extends DefaultClientConfigImpl {FeignOptionsClientConfig(Request.Options options) { setProperty(CommonClientConfigKey.ConnectTimeout, options.connectTimeoutMillis()); setProperty(CommonClientConfigKey.ReadTimeout, options.readTimeoutMillis()); }Override public void loadProperties(String clientName) {}Override public void loadDefaultValues() {}} } 在动态代理调用的那里我们得出一个结论那就是最后会调用Client接口的execute方法的实现所以我们就看一下execute方法的实现这里就是一堆操作从请求的URL中拿到了clientName也就是服务名。 为什么可以拿到服务名 其实很简单OpenFeign构建动态代理的时候传入了一个HardCodedTarget当时说在构建HardCodedTarget的时候传入了一个url那个url当时说了其实就是http://服务名所以到这里虽然有具体的请求接口的路径但是还是类似 http://服务名/api/sayHello这种所以可以通过路径拿到你锁请求的服务名。 拿到服务名之后再拿到了一个配置类IClientConfig最后调用lbClient我们看一下lbClient的方法实现。 private FeignLoadBalancer lbClient(String clientName) { return this.lbClientFactory.create(clientName);} 就是调用CachingSpringLoadBalancerFactory的create方法 public FeignLoadBalancer create(String clientName) { FeignLoadBalancer client this.cache.get(clientName); if (client ! null) { return client; } IClientConfig config this.factory.getClientConfig(clientName); ILoadBalancer lb this.factory.getLoadBalancer(clientName); ServerIntrospector serverIntrospector this.factory.getInstance(clientName, ServerIntrospector.class); client this.loadBalancedRetryFactory ! null ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector, this.loadBalancedRetryFactory) : new FeignLoadBalancer(lb, config, serverIntrospector); this.cache.put(clientName, client); return client; } 这个方法先根据服务名从缓存中获取一个FeignLoadBalancer获取不到就创建一个。 创建的过程就是从每个服务对应的容器中获取到IClientConfig和ILoadBalancer。Ribbon那篇文章都讲过这些核心类这里不再赘述。 默认就是创建不带spring重试功能的FeignLoadBalancer放入缓存最后返回这个FeignLoadBalancer。所以第一次来肯定没有需要构建也就是最终一定会返回FeignLoadBalancer所以我们通过lbClient方法拿到的是FeignLoadBalancer。从这里可以看出CachingSpringLoadBalancerFactory是构建FeignLoadBalancer的工厂类只不过先从缓存中查找找不到再创建FeignLoadBalancer。 拿到FeignLoadBalancer之后就会调用executeWithLoadBalancer接收到Response之后直接返回。 三、FeignLoadBalancer 那么这个FeignLoadBalancer又是啥呢这里放上FeignLoadBalancer核心源码。 public class FeignLoadBalancer extends AbstractLoadBalancerAwareClientFeignLoadBalancer.RibbonRequest, FeignLoadBalancer.RibbonResponse {private final RibbonProperties ribbon;protected int connectTimeout;protected int readTimeout;protected IClientConfig clientConfig;protected ServerIntrospector serverIntrospector;public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector) { super(lb, clientConfig); this.setRetryHandler(RetryHandler.DEFAULT); this.clientConfig clientConfig; this.ribbon RibbonProperties.from(clientConfig); RibbonProperties ribbon this.ribbon; this.connectTimeout ribbon.getConnectTimeout(); this.readTimeout ribbon.getReadTimeout(); this.serverIntrospector serverIntrospector; }Override public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride) throws IOException { Request.Options options; if (configOverride ! null) { RibbonProperties override RibbonProperties.from(configOverride); options new Request.Options(override.connectTimeout(this.connectTimeout), override.readTimeout(this.readTimeout)); } else { options new Request.Options(this.connectTimeout, this.readTimeout); } Response response request.client().execute(request.toRequest(), options); return new RibbonResponse(request.getUri(), response); } }  FeignLoadBalancer继承自AbstractLoadBalancerAwareClientAbstractLoadBalancerAwareClient又是啥玩意看过我写的关于Ribbon核心组件已经运行原理的那篇文章小伙伴肯定知道AbstractLoadBalancerAwareClient类主要作用是通过ILoadBalancer组件获取一个Server然后基于这个Server重构了URI也就是将你的请求路径http://服务名/api/sayHello转换成类似http://192.168.1.101:8088/api/sayHello这种路径也就是将原服务名替换成服务所在的某一台机器ip和端口替换之后就交由子类实现的exceut方法来发送http请求。 所以我们知道调用executeWithLoadBalancer之后就会重构请求路径将服务名替换成某个具体的服务器所在的ip和端口之后交给子类execute来处理对于这里来说也就是FeignLoadBalancer的execute方法因为FeignLoadBalancer继承AbstractLoadBalancerAwareClient。 直接定位到execute方法最核心的一行代码 Response response  request.client().execute(request.toRequest(), options); request.client()就会拿到构建LoadBalancerFeignClient传入的那个Client的实现我提到过这个Client的实现是具体发送请求的实现默认的就是Client.Default类不是默认就有可能是基于HttpClient或者是OkHttp的实现。所以这行代码就是基于这个Client就成功的发送了Http请求拿到响应然后将这个Response 封装成一个RibbonResponse返回最后就返回给MethodHandler然后解析响应封装成方法的返回值返回给调用者。 好了其实到这里就完全知道Feign是如何整合Ribbon的LoadBalancerFeignClient其实是OpenFeign适配Ribbon的入口FeignLoadBalancer才是真正实现选择负载均衡发送http请求的组件因为他继承了AbstractLoadBalancerAwareClient。 为了大家能够清楚的知道整个动态代理的调用过程我在Ribbon的那张图的基础上加上Feign的调用链路。 通过这张图我们可以清楚地看出OpenFeign、Ribbon以及注册中心之间的协同关系。 四、总结 到这里我通过三篇文章算上Nacos那两篇总共五篇文章完整的讲述了在微服务架构中OpenFeign、Ribbon、Nacos当然其它注册中心也可以这三个组件协同工作的核心源码和流程。这里我再用简洁的话来总结一下他们的协同工作原理OpenFeign在进行rpc调用的时候由于不知道服务具体在哪台机器上所以需要Ribbon这个负载均衡组件从服务所在的机器列表中选择一个Ribbon中服务所在的机器列表是从注册中心拉取的Ribbon提供了一个ServerList接口注册中心实现之后Ribbon就可以获取到服务所在的机器列表这就是这三个组件最基本的原理。希望通过这五篇文章小伙伴们可以对微服务架构的最基本的原理有一定的了解同时也对OpenFeign、Ribbon、Nacos源码有一定的认识。

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

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

相关文章

学校网站建设招标公告2网站建设总结

目录 安装步骤一、清除所有残留的旧MySQL二、安装MySQL 报错问题1. 提示未找到匹配的参数: mysql-community-server2. 公钥问题 安装步骤 一、清除所有残留的旧MySQL 1. 关闭MySQL [rootlocalhost /]# service mysqld stop Redirecting to /bin/systemctl stop …

机器学习 深度学习发展简史(简化版)

1. 1943:McCulloch & Pitts 提出人工神经元模型 —— 神经网络的雏形。2. 1957:Rosenblatt 提出感知机(Perceptron) —— 最早的可训练神经网络。 Rosenblatt 提出的 Perceptron 是一个 单层感知机(Single-la…

教培公司 —— 讲课评分表

教培公司 —— 讲课评分表本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注处,如有侵权请与博主联系。 如果未特殊…

2025无锡黄金上门回收公司权威推荐榜:专业估价与诚信服务口碑之选

在当今经济环境下,黄金作为重要的避险资产和投资工具,其回收市场日益活跃。随着黄金价格的持续波动,越来越多的企业和个人开始关注黄金回收这一领域。黄金回收不仅涉及资产变现,更关系到资源循环利用和经济效益最大…

详细介绍:告别“下次注意”,用这套结构化事故复盘方案就对了

详细介绍:告别“下次注意”,用这套结构化事故复盘方案就对了pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

完整教程:AI行业应用全景:从金融风控到智能制造的落地实践与技术解析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

关于树状数组的一些东西

本来以为背背板子就够用了的,发现有的时候会需要其中的一些东西。 原来树状数组也有自己的不可替代性。 但是像用树状数组做平衡树这种我确确实实不感兴趣。 当摸鱼写一些吧。 个人认为,树状数组是最能体现 OI 魅力的…

完整教程:量子机器学习深度探索:从原理到实践的全面指南

完整教程:量子机器学习深度探索:从原理到实践的全面指南2025-10-02 15:13 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important…

[问题记录] vmagent 增加 aggregation 表达式后,CPU 上升 2.43 倍, 内存上升 3.82 倍

[问题记录] vmagent 增加 aggregation 表达式后,CPU 上升 2.43 倍, 内存上升 3.82 倍作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!cnblogs博客 zhihu Github 公众号:一本正经的瞎扯在这篇文章:「Vic…

济南做网站的中企一键logo设计app

题目 输入一个树状天平,根据力矩相等原则判断是否平衡。如图6-5所示,所谓力矩相等,就是WlDlWrDr,其中Wl和Wr分别为左右两边砝码的重量,D为距离。采用递归(先序)方式输入:每个天平的…

lazyVIM整体介绍、常用功能和插件

LazyVim 是一个基于 Neovim + Lazy.nvim 插件管理器 构建的现代化、模块化、开箱即用的 Neovim 配置框架。它极大降低了 Neovim 的使用门槛,同时保留了高度可定制性。 下面为你详细介绍 LazyVim 中的常用插件和核心功…

广州建站公司网站图片设计在线

正则表达式匹配的是文本内容,linux的文本三剑客 都是针对文本内容 grep 过滤文本内容 sed 针对文本内容进行增删改查 awk 按行取列 文本三剑客都是按行进行匹配。 grep grep 的作用就是使用正则表达式来匹配文本内容 选项: -m …

云校网站建设上海网址一360导航

对之前文章的补充:MyBatis中的#{}与${}注入问题----原文链接 前言: MyBatis是一个流行的Java持久层框架,用于将对象与数据库中的数据进行映射。然而,如果不当使用,MyBatis也可能受到诸如SQL注入这类的安全问题的影响。…

vue网站开发教程设计师用什么软件设计效果图

本文使用 Zhihu On VSCode 创作并发布跨时钟域同步(异步FIFO)之前学习了跨时钟域下的单bit信号同步的方法,这些单bit信号多是作为控制信号或者标志信号来使用,再实际的项目中,处理多bit数据也是十分常见的,…

互联网项目各阶段素材驱动与AI技术的深度运用策略

互联网项目各阶段素材驱动与AI技术的深度运用策略pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

【SpringAI】第四弹:深入解析 Rag 检索增强工作流程、最佳实践和调优 - 详解

【SpringAI】第四弹:深入解析 Rag 检索增强工作流程、最佳实践和调优 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

2025 年浮动密封厂家 TOP 企业品牌推荐排行榜,矿用,工程机械,矿山机械,煤矿井下,煤矿机械浮动密封推荐这十家公司!

在工业领域,浮动密封的重要性不言而喻,其性能优劣直接关乎设备的运行稳定性、使用寿命及生产效率。然而,当前浮动密封市场鱼龙混杂,产品质量参差不齐。部分厂家工艺落后,导致密封效果不佳,频繁出现泄漏问题,不仅…

P2141 [NOIP 2014 普及组] 珠心算测验

简易题解 题目大意 给定一个包含 \(n\) 个互不相同的正整数的集合。我们需要找出这个集合中有多少个数字,恰好等于集合中另外两个不同数字的和。 思路分析 题目要求我们找出满足 A = B + C 形式的数字 A,其中 A, B, …

CF1081F Tricky Interactor

比较狗蛋的题目。 首先发现随机,一般这种随机题次数也是随机的。 然后发现操作的性质,每两次操作要么不变,要么除了这个区间内的数都翻转,然后我们每次查询 \([i, i]\),先用 \(4\) 次操作将它查出来,再用 \(4\) …

2025.10 做题笔记

MAO!MAO! GIVE ME LOVE 君 gimmick gimmick LOVE どうか笑ってダーリン MAO! GIVE ME LOVE 君 gimmick gimmick LOVE 今夜最後まで 鳴らせ——洛天依《MAO!》AT_arc121_e 思维难度:\(\color{#FFC116} 黄\) *1500 这也…