Hystrix - 微服务韧性演进史:从 Hystrix 到 Service Mesh

Hystrix - 微服务韧性演进史:从 Hystrix 到 Service Mesh
在这里插入图片描述
👋 大家好,欢迎来到我的技术博客!
💻 作为一名热爱 Java 与软件开发的程序员,我始终相信:清晰的逻辑 + 持续的积累 = 稳健的成长
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕Hystrix这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!

文章目录

Hystrix - 微服务韧性演进史:从 Hystrix 到 Service Mesh 🚀

在当今这个高度互联、瞬息万变的数字时代,微服务架构已成为构建大规模分布式系统的主要范式。然而,随着服务数量的爆炸式增长和相互依赖关系的日趋复杂,如何保障系统的稳定性、可靠性和韧性(Resilience),成为每一个架构师和工程师必须面对的核心挑战。在这一背景下,熔断器模式(Circuit Breaker Pattern)应运而生,它如同一道坚固的防线,能够有效防止级联故障,确保系统在部分组件失效时仍能保持基本功能。

Netflix Hystrix 的出现,无疑是微服务韧性设计领域的一个里程碑。它以其强大的熔断、降级、限流能力,成为了无数 Java 微服务架构的基石。然而,正如所有技术一样,Hystrix 也走到了它的生命周期尽头。随着 Spring Cloud 的演进和云原生理念的深入人心,一种全新的、更具前瞻性的微服务韧性设计范式——服务网格(Service Mesh)应运而生。本文将带你穿越微服务韧性的演进历程,从 Hystrix 的辉煌到 Service Mesh 的崛起,揭示微服务架构中应对复杂性和不确定性的终极武器。


🧠 一、什么是微服务韧性?为何如此重要?

📌 为什么需要韧性?

想象一下,一个典型的电商系统:用户下单 → 商品服务检查库存 → 支付服务处理支付 → 物流服务安排发货。任何一个环节出现问题(比如数据库宕机、网络延迟、第三方 API 崩溃),都可能导致整个交易流程失败,甚至引发雪崩效应(Cascading Failures)——一个服务的故障迅速传导至其他服务,最终导致整个系统瘫痪。这就是“脆弱性”的体现。

韧性(Resilience)是指系统在面对异常、故障或压力时,能够快速恢复、继续运行并提供基本服务的能力。它不仅仅是“不崩溃”,更是“在困境中保持有用”。

🧱 微服务架构下的挑战

微服务将系统拆分为多个独立的小服务,虽然带来了灵活性、可扩展性等优势,但也引入了新的复杂性:

  1. 服务间调用增多:服务 A 调用服务 B,B 调用 C,C 调用 D…… 调用链路变得复杂。
  2. 故障传播风险:一个服务的失败可能像多米诺骨牌一样,影响到下游所有依赖它的服务。
  3. 网络不确定性:网络延迟、丢包、超时等问题无处不在。
  4. 缺乏统一治理:每个服务可能采用不同的容错策略,缺乏统一的管理和监控。

因此,构建一个具有韧性的微服务系统,意味着要在分布式环境中,为每一个服务调用都建立一套有效的防护机制。


🏗️ 二、Hystrix 的诞生:从 Netflix 开始的熔断之旅

📦 Hystrix 的历史背景

Netflix 作为全球领先的流媒体平台,其系统面临着海量用户并发访问的压力和复杂的分布式环境。为了应对这些挑战,Netflix 开发了 Hystrix,旨在通过提供一系列容错和恢复机制,增强其服务的鲁棒性。

Hystrix 不仅仅是一个熔断器,它是一个完整的容错库,集成了熔断、降级、限流、隔离等多种机制,为微服务架构提供了坚实的基础。

🛠️ Hystrix 的核心机制

1. 熔断器模式 (Circuit Breaker)

这是 Hystrix 最核心的功能。它模拟了现实世界中的电路保险丝:当线路中电流过大(即请求失败率过高)时,保险丝会熔断,切断电源,防止更大的损害。在 Hystrix 中,当某个服务的失败率超过设定阈值(如 50%),熔断器会打开(Open),后续对该服务的请求会立即失败,而不是等待超时或进行无效调用。经过一段预设时间(Wait Duration),熔断器进入半开(Half-Open)状态,允许部分请求通过,验证服务是否恢复。如果成功,则恢复正常(Closed);如果失败,则再次熔断。

2. 隔离 (Isolation)

Hystrix 通过线程池或信号量来实现请求隔离。不同服务的调用被分配到不同的线程池中,即使某个服务的调用阻塞,也不会影响到其他服务的执行。这有效避免了因个别服务拖慢整个应用而导致的性能问题。

3. 降级 (Fallback)

当服务调用失败(无论是熔断还是超时)时,Hystrix 可以执行预先定义好的降级逻辑。例如,返回默认值、缓存数据、或者调用备用服务,确保用户体验不至于完全中断。

4. 限流 (Rate Limiting)

虽然 Hystrix 的限流不如其熔断功能那样突出,但它也支持通过线程池大小等方式来限制并发请求数量,防止服务过载。

💡 Java 代码示例:Hystrix 的基础使用

让我们通过一个简单的例子来体验 Hystrix 的魅力。假设我们有一个 PaymentService,它负责处理支付请求。

首先,添加 Maven 依赖:

<dependency><groupId>com.netflix.hystrix</groupId><artifactId>hystrix-core</artifactId><version>1.5.18</version><!-- 注意:Hystrix 已停止维护 --></dependency>

然后,创建一个继承自 HystrixCommand 的命令类:

packagecom.example.demo.hystrix;importcom.netflix.hystrix.HystrixCommand;importcom.netflix.hystrix.HystrixCommandGroupKey;importcom.netflix.hystrix.HystrixCommandProperties;importcom.netflix.hystrix.HystrixThreadPoolKey;importcom.netflix.hystrix.HystrixThreadPoolProperties;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.util.concurrent.TimeUnit;publicclassPaymentCommandextendsHystrixCommand<String>{privatestaticfinalLogger logger =LoggerFactory.getLogger(PaymentCommand.class);privatefinalString orderId;// 订单 IDprivatefinaldouble amount;// 金额// 构造函数publicPaymentCommand(String orderId,double amount){super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("PaymentService")).andCommandKey(HystrixCommandKey.Factory.asKey("ProcessPayment"))// 命令键.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PaymentThreadPool"))// 线程池键.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(1000)// 执行超时时间.withCircuitBreakerRequestVolumeThreshold(10)// 熔断器触发最小请求数.withCircuitBreakerErrorThresholdPercentage(50)// 错误百分比阈值.withCircuitBreakerSleepWindowInMilliseconds(5000)// 熔断器休眠时间).andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(10)// 线程池核心大小.withMaxQueueSize(100)// 最大队列大小));this.orderId = orderId;this.amount = amount;}/** * 真正执行业务逻辑的方法 */@OverrideprotectedStringrun()throwsException{ logger.info("开始处理订单 {} 的支付,金额: {}", orderId, amount);// 模拟支付服务调用// 这里可以是真实的 HTTP 请求、数据库操作等if(Math.random()>0.8){// 模拟 20% 的失败率thrownewRuntimeException("支付服务暂时不可用");}// 模拟耗时TimeUnit.MILLISECONDS.sleep(500); logger.info("订单 {} 支付成功", orderId);return"SUCCESS";}/** * 当 run 方法抛出异常或超时时,调用此方法执行降级逻辑 */@OverrideprotectedStringgetFallback(){ logger.warn("支付服务降级,订单 {} 处理失败", orderId);// 返回默认值或执行备用逻辑return"FAIL: Payment Service Unavailable - Fallback Executed";}}

现在,我们来测试一下这个命令:

packagecom.example.demo;importcom.example.demo.hystrix.PaymentCommand;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;publicclassHystrixDemoApplication{privatestaticfinalLogger logger =LoggerFactory.getLogger(HystrixDemoApplication.class);publicstaticvoidmain(String[] args){ logger.info("开始 Hystrix 示例演示...");// 创建并执行命令for(int i =0; i <15; i++){PaymentCommand command =newPaymentCommand("ORDER_"+ i,100.0);String result = command.execute();// execute() 会阻塞直到得到结果 logger.info("订单 {} 的支付结果: {}","ORDER_"+ i, result);}// 输出 Hystrix 的监控信息(如果启用了仪表板) logger.info("Hystrix 监控信息可以通过 Hystrix Dashboard 查看");}}
📌 说明:上述代码展示了 Hystrix 的核心用法。run() 方法包含实际的业务逻辑,getFallback() 方法是降级逻辑。Hystrix 通过 Setter 配置了熔断器参数、线程池参数等。

⚠️ Hystrix 的局限性

尽管 Hystrix 功勋卓著,但其局限性也逐渐显现:

  1. 维护停滞:Netflix 官方在 2018 年宣布 Hystrix 停止维护,不再更新新功能,安全漏洞难以修复。
  2. 侵入性强:需要在业务代码中显式地包裹 HystrixCommand,增加了代码复杂度。
  3. 依赖 Spring Cloud:在 Spring Cloud 中,Hystrix 与 Eureka、Ribbon 等组件紧密耦合,但随着 Spring Cloud 的演进(如 Hoxton 版本后移除 Hystrix),其兼容性问题日益突出。
  4. 功能有限:虽然 Hystrix 提供了基本的熔断、降级、限流,但在服务网格时代,更需要的是统一、透明的、非侵入式的治理能力。

🧱 三、Resilience4j:轻量级的弹性新星

📦 Resilience4j 的兴起

在 Hystrix 停止维护之后,社区迅速涌现了多个替代方案。其中,Resilience4j 以其轻量级、现代化、函数式编程风格脱颖而出,成为许多开发者的首选。

Resilience4j 是一个专为 JVM 设计的弹性库,它专注于提供一系列轻量级的容错机制。与 Hystrix 不同,它没有庞大的依赖树,设计上更加简洁,易于理解和使用。

🛠️ Resilience4j 的核心特性

1. 轻量级与模块化

Resilience4j 的设计目标之一就是轻量级。它不像 Hystrix 那样庞大,而是采用模块化设计,你可以只引入需要的模块(如 resilience4j-circuitbreaker, resilience4j-ratelimiter)。

2. 函数式编程风格

Resilience4j 鼓励使用函数式编程的方式。它提供了 Supplier, Function 等接口,允许你以组合的方式将容错逻辑应用于业务代码,减少了侵入性。

3. 与 Spring Boot 集成良好

Resilience4j 提供了与 Spring Boot 和 Spring Cloud 的良好集成,通过 @CircuitBreaker, @RateLimiter 等注解,可以非常方便地在 Spring 应用中启用容错功能。

4. 丰富的容错机制
  • 熔断 (Circuit Breaker):支持多种熔断策略。
  • 限流 (Rate Limiter):基于令牌桶算法,支持精确控制。
  • 重试 (Retry):支持指数退避等策略。
  • 隔离 (Bulkhead):通过舱壁隔离(类似 Hystrix 的线程池)防止故障扩散。
  • 缓存 (Cache):提供简单的缓存机制。

💡 Java 代码示例:Resilience4j 的基础使用

我们使用 Resilience4j 来重构上面的支付服务示例。

添加 Maven 依赖:

<dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-spring-boot2</artifactId><version>2.1.0</version><!-- 使用最新稳定版 --></dependency>

application.yml 中配置:

resilience4j:circuitbreaker:instances:paymentService:failure-rate-threshold:50# 失败率阈值wait-duration-in-open-state: 30s # 熔断持续时间permitted-number-of-calls-in-half-open-state:3# 半开状态允许的请求数sliding-window-size:10# 滑动窗口大小minimum-number-of-calls:5# 最少请求数rate-limiter:instances:paymentService:limit-for-period:10# 每秒允许的请求数limit-refresh-period: 1s # 刷新周期timeout-duration: 100ms # 获取令牌超时时间

创建服务类:

packagecom.example.demo.resilience4j;importio.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;importio.github.resilience4j.ratelimiter.annotation.RateLimiter;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.stereotype.Service;importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.TimeUnit;@ServicepublicclassPaymentService{privatestaticfinalLogger logger =LoggerFactory.getLogger(PaymentService.class);// 使用 @CircuitBreaker 注解定义熔断逻辑@CircuitBreaker(name ="paymentService", fallbackMethod ="fallbackProcessPayment")// 使用 @RateLimiter 注解定义限流逻辑@RateLimiter(name ="paymentService")publicStringprocessPayment(String orderId,double amount)throwsInterruptedException{ logger.info("开始处理订单 {} 的支付,金额: {}", orderId, amount);// 模拟支付服务调用if(Math.random()>0.8){// 模拟 20% 的失败率thrownewRuntimeException("支付服务暂时不可用");}// 模拟耗时TimeUnit.MILLISECONDS.sleep(500); logger.info("订单 {} 支付成功", orderId);return"SUCCESS";}// 熔断后的降级方法publicStringfallbackProcessPayment(String orderId,double amount,Exception ex){ logger.warn("支付服务降级,订单 {} 处理失败: {}", orderId, ex.getMessage());return"FAIL: Payment Service Unavailable - Fallback Executed";}// 异步处理示例publicCompletableFuture<String>processPaymentAsync(String orderId,double amount){returnCompletableFuture.supplyAsync(()->{try{returnprocessPayment(orderId, amount);// 可以在这里调用同步方法}catch(InterruptedException e){Thread.currentThread().interrupt();thrownewRuntimeException(e);}});}}

控制器:

packagecom.example.demo.controller;importcom.example.demo.resilience4j.PaymentService;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importjava.util.concurrent.CompletableFuture;@RestControllerpublicclassPaymentController{privatestaticfinalLogger logger =LoggerFactory.getLogger(PaymentController.class);@AutowiredprivatePaymentService paymentService;@GetMapping("/payment/process")publicStringprocessPayment(@RequestParamString orderId,@RequestParamdouble amount){ logger.info("接收到支付请求,订单 ID: {}, 金额: {}", orderId, amount);try{// 调用服务String result = paymentService.processPayment(orderId, amount); logger.info("支付结果: {}", result);return result;}catch(Exception e){ logger.error("处理支付时发生异常: ", e);return"ERROR: "+ e.getMessage();}}// 异步调用示例@GetMapping("/payment/processAsync")publicCompletableFuture<String>processPaymentAsync(@RequestParamString orderId,@RequestParamdouble amount){ logger.info("接收到异步支付请求,订单 ID: {}, 金额: {}", orderId, amount);return paymentService.processPaymentAsync(orderId, amount);}}

🔄 与 Hystrix 的对比

特性HystrixResilience4j
轻量级中等(依赖较多)非常轻量
函数式编程支持
Spring Boot 集成需要额外依赖内置支持
侵入性高(需要继承 Command)低(注解驱动)
维护状态已停止维护积极维护
文档与社区成熟成长中但活跃

🌐 四、Service Mesh:微服务治理的新范式

📦 Service Mesh 的诞生与定义

随着微服务架构的普及,服务间调用的复杂性日益增加。传统的在应用层实现的容错机制(如 Hystrix)虽然有效,但存在侵入性强、难以统一管理等问题。服务网格(Service Mesh)作为一种新兴的基础设施层,应运而生。

Service Mesh 是一个专门用于处理服务间通信的基础设施层。它通过在每个服务实例旁边注入一个轻量级的代理(Sidecar),将服务间的通信交给这个代理来处理,从而实现了对服务间通信的透明治理。

🛠️ Service Mesh 的核心能力

1. 非侵入性治理

服务网格最大的优势在于其非侵入性。服务本身的代码不需要修改,所有的流量管理、安全策略、监控等都是由 Sidecar 代理来完成的。这极大地降低了服务改造的成本。

2. 统一的策略控制

服务网格提供了一个统一的策略中心,可以集中管理所有服务的流量规则、安全策略、熔断降级等。这使得运维和架构师可以在不改动任何业务代码的情况下,动态调整服务行为。

3. 强大的流量管理

服务网格支持复杂的流量管理功能:

  • 负载均衡
  • 路由规则(如基于请求头、路径等进行路由)
  • 超时与重试
  • 熔断与降级
  • 限流
  • 灰度发布/金丝雀发布
4. 可观测性

服务网格天然具备强大的可观测性能力,可以收集详细的追踪数据(Tracing)、指标(Metrics)和日志(Logging),为系统监控和故障排查提供有力支持。

5. 安全与认证

服务网格可以提供服务间通信的安全保障,如 mTLS(双向 TLS)、身份认证、授权(RBAC)等,确保服务通信的安全性。

💡 Java 代码示例:Istio Service Mesh 中的配置

我们以 Kubernetes 和 Istio 为例,展示如何通过配置文件来实现服务网格的容错能力。

🧩 前提条件
  • 已部署 Kubernetes 集群
  • 已安装 Istio
📄 配置文件示例
  1. DestinationRule:定义服务的流量策略,包括熔断规则。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata:name: payment-service spec:host: payment-service # 目标服务的主机名trafficPolicy:connectionPool:http:maxRequestsPerConnection:10# 每个连接最大请求数outlierDetection:# 熔断配置consecutiveErrors:5# 连续错误次数interval: 10s # 检查间隔baseEjectionTime: 30s # 被熔断的时间maxEjectionPercent:100# 最大熔断百分比# 可以在这里添加限流规则---apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata:name: payment-service spec:hosts:- payment-service http:-route:-destination:host: payment-service port:number:8080# 服务端口
  1. Fault Injection:模拟服务故障,测试熔断效果。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata:name: payment-service-fault-injection spec:hosts:- payment-service http:-fault:abort:percentage:value:50# 50% 的请求会被中断httpStatus:503# 返回 503 错误route:-destination:host: payment-service port:number:8080
  1. Rate Limiting:通过 EnvoyFilter 实现限流(这是一个高级用法)。
# 这是一个简化的示例,实际限流通常通过 Istio 的 Quota Spec 或 Envoy Filter 实现apiVersion: config.istio.io/v1alpha2 kind: QuotaSpec metadata:name: payment-service-quota spec:rules:-selector:matchLabels:service: payment-service quotas:-quota: payment-service-quota charge:1---apiVersion: config.istio.io/v1alpha2 kind: QuotaSpecBinding metadata:name: payment-service-quota-binding spec:quotaSpecs:-name: payment-service-quota namespace: default subjects:-user:"*"
🚀 部署流程
  1. 将上述 YAML 文件保存为 payment-service.yaml
  2. 使用 kubectl apply -f payment-service.yaml 命令将其部署到 Kubernetes 集群。
  3. 验证配置是否生效:kubectl get destinationrule,payment-service -o yaml
📌 注意:Istio 的配置非常复杂,需要深入了解其架构和概念。它更适合于大型、复杂的微服务集群,而非单个服务的简单容错。部署和管理服务网格通常需要专业的运维知识。

📊 五、演进之路:从 Hystrix 到 Service Mesh 的选型矩阵

为了更清晰地理解不同技术方案的演进和适用场景,我们绘制一张选型矩阵图:

典型场景

技术演进

简单应用

单体应用/小型微服务

小型/中型微服务

大型复杂微服务

演进阶段

传统单体应用

Hystrix 时代

Resilience4j 时代

Service Mesh 时代

无特殊容错机制

服务内嵌 Hystrix

服务内嵌 Resilience4j

服务网格治理

🧭 从 Hystrix 到 Service Mesh 的演进路径

  1. 起步阶段(传统单体应用):应用本身不具备容错能力,故障影响范围广。
  2. 初期阶段(Hystrix 时代):在应用内部引入 Hystrix,为单个服务提供容错保护。这是微服务架构早期的主流做法,虽然有效,但存在侵入性和管理复杂度高的问题。
  3. 成熟阶段(Resilience4j 时代):在 Hystrix 停止维护后,Resilience4j 等轻量级方案兴起。它提供了更现代、更轻量的容错能力,同时与 Spring 生态集成良好,成为许多团队的过渡选择。
  4. 未来阶段(Service Mesh 时代):服务网格代表了微服务治理的未来方向。它将容错、安全、监控等能力下沉到基础设施层,实现了真正的非侵入式治理。对于大规模、复杂的微服务系统,服务网格是最佳选择。

📈 技术演进趋势分析

  • 从应用层到基础设施层:容错能力从应用代码内部转移到了更底层的基础设施(服务网格)。
  • 从侵入性到非侵入性:服务网格让业务代码几乎不受影响,专注于核心业务逻辑。
  • 从分散到统一:服务网格提供了一个统一的平台来管理所有服务的治理策略。
  • 从被动到主动:服务网格不仅提供容错,还能主动进行流量优化、安全加固和智能路由。

🧾 六、结论与展望

微服务韧性演进的历史,是一部不断探索、创新和优化的历史。从 Netflix Hystrix 的开创性工作,到 Resilience4j 的轻量级革新,再到 Service Mesh 的基础设施化治理,每一次演进都反映了业界对构建更健壮、更灵活、更可扩展的分布式系统的需求。

Hystrix 作为先行者,为我们奠定了坚实的理论和实践基础。虽然它已经停止维护,但其设计理念和核心机制仍然值得我们学习和借鉴。

Resilience4j 作为新一代的弹性库,以其轻量、现代化和良好的集成性,为中小型微服务提供了高效的解决方案。

Service Mesh 则代表了微服务架构的未来。它将服务治理提升到了一个新的高度,通过非侵入性、统一化的管理,解决了大规模微服务架构下的复杂性和管理难题。

选择哪种技术方案,取决于你的具体需求、团队能力和系统规模。无论处于哪个阶段,拥抱变化、持续演进,才是构建韧性系统的永恒主题。🚀


📚 参考资料与延伸阅读


愿你的微服务系统,如磐石般坚韧,如流水般灵活!🌟


🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

Read more

【C++:哈希表封装】用哈希表封装unordered_map和unordered_set

【C++:哈希表封装】用哈希表封装unordered_map和unordered_set

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶、测试开发要点全知道 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的C++专栏简介: C++的两个参考文档  老朋友(非官方文档):cplusplus 官方文档(同步更新):C++ 官方参考文档 set和multiset的参考文档:set、multiset map和multimap的参考文档:map、multimap unordered_set和unordered_multiset的参考文档:unordered_set、unordered_multiset unordered_map和unordered_multimap的参考文档: unordered_map、unordered_

By Ne0inhk
Flutter 组件 humanize 的适配 鸿蒙Harmony 深度进阶 - 驾驭多语言复数逻辑算法、实现鸿蒙端中式大额单位感知与极致人性化文本渲染方案

Flutter 组件 humanize 的适配 鸿蒙Harmony 深度进阶 - 驾驭多语言复数逻辑算法、实现鸿蒙端中式大额单位感知与极致人性化文本渲染方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 humanize 的适配 鸿蒙Harmony 深度进阶 - 驾驭多语言复数逻辑算法、实现鸿蒙端中式大额单位感知与极致人性化文本渲染方案 前言 在前文我们掌握了 humanize 进行基础数据转换的方法。但在鸿蒙(OpenHarmony)面向全球市场的布局中,真正的技术挑战往往隐藏在极其琐碎的“语言表达”中。例如:在英文中我们说 1 items 是错误的,必须是 1 item 与 2 items;而在中文环境下,我们虽然没有复数形变,但却有“万、亿”这类独特的四位一级计数逻辑。 一个真正具备“高级感”的鸿蒙应用,不应在数据展示上显得僵硬且带有明显的机器翻译痕迹。 本文将作为 humanize 适配的进阶篇,带你攻克多语言复数(Pluralization)

By Ne0inhk

傅里叶变换 | FFT 与 DFT 原理及算法

注:本文为 “傅里叶变换 | FFT 与 DFT” 相关合辑。 英文引文,机翻未校。 中文引文,略作重排。 图片清晰度受引文原图所限。 如有内容异常,请看原文。 Fast Fourier Transform (FFT) 快速傅里叶变换(FFT) In this section we present several methods for computing the DFT efficiently. In view of the importance of the DFT in various digital signal processing applications, such as linear filtering,

By Ne0inhk
优选算法——双指针专题 3.快乐数 4.盛水最多的容器

优选算法——双指针专题 3.快乐数 4.盛水最多的容器

优选算法——双指针专题 3.快乐数 4.盛水最多的容器 一.快乐数 1.题目解析 [题目传送门](202. 快乐数 - 力扣(LeetCode)) 2.原理解析 第一种情况:数最后变成1 第二种情况:无限循环但不是1 但两种都可以抽象成一种,有点像之前做过的带环链表 解法:快慢双指针 1.定义快慢指针 2.慢指针每次向后移动一步,快指针每次向后移动两步 3.判断相遇时候的值 3.代码实现 classSolution{public:intBitSum(int n)//返回每一位数上的平方和{int sum=0;while(n){int m=n%10;

By Ne0inhk