当前位置: 首页 > news >正文

消息队列进阶-1.消息队列的应用场景与选型

  • 👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家
  • 📕系列专栏:Spring源码、JUC源码、Kafka原理
  • 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
  • 🍂博主正在努力完成2023计划中:源码溯源,一探究竟
  • 📝联系方式:nhs19990716,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀

文章目录

  • 消息队列的应用场景
    • 从秒杀开始说起
    • 异步处理
    • 流量控制
    • 服务解耦
      • 非常多的应用场景
  • 消息队列选型的基本标准
    • 选择消息队列的基本标准
    • 可供选择的消息队列
      • RabbitMQ
      • RocketMQ
      • Kafka
  • 消息队列的消费模式
    • 队列模型
    • 发布-订阅模型
    • RabbitMQ的消息模型
    • RocketMQ的消息模型
    • Kafka的消息模型

消息队列的应用场景

从秒杀开始说起

在这里插入图片描述

类似于秒杀的场景,短时间内需要处理大量的请求的,需要涉及两个东西,一个是缓存,一个是MQ。

首先从头来分析整个的流程到底是什么样的。

假如说我想举行一个秒杀活动,我想定在明天上午的十点,所以这个事就需要我们的运维人员提前通过 秒杀活动管理服务配置秒杀活动及更改 ,后面有个动作就是 双写异步通知 将秒杀活动的信息同步到 缓存数据库 中,此时 查询秒杀活动 可以从 缓存 中去查询。

当配置完成后,还需要发送一个 MQ 去进行 秒杀活动变更通知 ,那么谁去处理呢? 一个是 **秒杀页面渲染服务 **

一个是 库存中心 ,对于库存中心来说,它所做的就是 活动变更/更新库存/释放冻结 。对于我们的 秒杀页面渲染服务 我们打开前台的页面,应该是静态的,而我们少部分的活动信息,应该是动态的,所以我们应该为其生成这样的静态页面。基于模板技术渲染出HTML 渲染出来之后 推送给Nginx ,这样的话,将来不用访问后端服务,直接到Nginx就可以拿到我们的所对应的秒杀商品的信息。但是光到这一步还是不够的,因为用户是天南海北的,都打到北京机房,可能扛不住,所以需要 向 CDN服务器 推送静态 ,由CDN做负载均衡,分配到就近的机房上。这样的话,这一路就差不多了。

对于我们的用户来说,他登陆到我们的 商城系统,就可以参与我们的 秒杀

在这之前需要进行一个 时间同步服务 主要涉及到一个 秒杀授时 的问题,

当开始 点击秒杀按钮 30s内只能点击一次 但是我们不能只考虑到正常的流量,我们还需要考虑商业程序批量来的用户流量。这里面有主要的限流手段,如 商业验证码防刷限流 大数据+AI判断验证码 DDoc高防 进行这些过程后 流量清洗 就能到达我们的设备,也就是到了 Nginx 其内部也要进行 内部限流 比如只允许超过库存10%请求

假如说参加活动的有100w人,但是实际能抢到茅台的只有1000个人,对于大部分请求来说是不需要处理的,先到先得。但是考虑到有一部分人下单失败,下单了没有进行支付等等,所以进行限流控制。

此时到了我们 反作弊服务 经过我们的 大数据分析 看看是不是 异常账号 僵尸账号

然后就是负载到了我们的 秒杀服务集群 ,此时我们就 可以用库存LUA脚本 去扣减Redis里面的库存。当扣减成功,也就意味着 秒杀成功零丢失 发送一个 MQ ,那么 秒杀下单服务 监听/消息积压/消息丢失/解决 此时就可以到我们的 订单系统 生成订单 然后去进行 支付

当然还需要考虑 失败/取消/回退库存 到redis集群,以及 秒杀下单服务的幂等解决重复下单问题

以上方案适合于短时间内来高并发的场景。

异步处理

秒杀系统需要解决的核心问题就是:利用有限的服务器资源,短时间内处理海量的请求。秒杀场景一定离不开的是缓存和消息队列。

处理一个秒杀请求包含了很多步骤,例如:

  • 风险控制
  • 库存锁定
  • 生成订单
  • 短信通知
  • 更新统计数据

如果没有任何优化,正常的处理流程是:APP将请求发送给网关,依次调用上述5个流程,然后将结果返回给APP。

决定秒杀是否成功,取决于两个动作:风险控制、库存锁定,后续生成订单、短信通知、更新统计,并不一定在秒杀请求中处理。

在这里插入图片描述

借助MQ将原来的5个步骤,减少为2个步骤。

  • 对于一些比较耗时的操作,通过消息队列进行了异步处理了,更快的返回结果。
  • 减少等待,实现了步骤的并发、提升了系统的性能。

异步还可以提升系统的伸缩性。

在这里插入图片描述

流量控制

错峰与流控,消峰与填谷。(因为前端 和 后端的流量处理能力不一样)

如何避免过多的请求压垮我们的秒杀系统呢?

设计思路:使用消息队列隔离网关和后端服务,以达到流量控制和保护后端服务的目的。

在这里插入图片描述

假如消息队列之后,整个秒杀的流程:

  • 网关收到请求后,将请求放入到MQ中。
  • 后端服务从请求MQ获取请求,完成后续秒杀处理过程,返回响应。

在这里插入图片描述

代价:

  • 增加系统调用链环节,导致总体的响应时延变长
  • 同步调用变成了异步调用,增加了系统的复杂度
  • 成本问题,MQ高性能 高可用

MQ太重了,可以考虑其他简单的实现方案:

常见限流算法:

  • 固定窗口算法
  • 滑动窗口算法
  • 漏桶算法
  • 令牌桶算法

令牌桶控制流量的原理是:单位时间内只发放固定数量的令牌到令牌桶中,规定服务在处理请求之前必须先从令牌桶中拿出来一个令牌,如果令牌桶中没有令牌,则拒绝请求。这样就保证单位时间内,能处理的请求不超过发放令牌的数量,起到了流量控制的作用。

在这里插入图片描述

而实现令牌的方式不像消息队列一样,不需要破坏原有的调用链,只要在网关里处理APP请求时增加一个获取令牌的逻辑。

服务解耦

微服务的通信模式:

  • 调用链模式(A 调用 B,B 调用 C,弊端就是调用链太长了,那么其实调用链的可用性就取决于每个服务的可用性相乘,总的来说可用性是下降的,性能的影响也是下降的)
  • 聚合器模式(业务聚合的情况,其实就是将原有比较长的一个调用链,缩减成两层)
  • 基于事件的异步模式

在这里插入图片描述

当新订单创建时:

  • 支付系统发起支付流程
  • 风控系统验证合法性
  • 消息系统发送短信
  • 运营系统需要更新统计数据

所有的电商都选择用消息队列来解决类似的系统耦合过于紧密的问题。引入消息队列后,订单服务在订单变化时发送一条消息到消息队列的一个主题Order中,所有下游系统都订阅主题Order,这样每个下游系统都可以获得一份实时完整的订单数据。

非常多的应用场景

  • 通过MQ实现分布式事务、最终一致性
  • 作为发布/订阅系统实现一个微服务级别的系统间的观察者模式
  • 连接流计算任务和大数据
  • 用于将消息广播给大量接收者,数据同步

消息队列选型的基本标准

选择消息队列的基本标准

  • 功能需求(引入消息队列能不能解决我现在的问题!)
  • 非功能需求(是否开源,社区维护,是否流行并且有一定的社区活跃度)

开源的话,如果在开发的过程中出现了bug,最起码你可以通过看源代码规避这个问题。 开源的话,网上有很多现成的解决方案,使用的人多,会和整体的生态有一个很好的兼容。

所以作为一款及格的消息队列产品,必须具备的几个特性包括:

  • 可靠性:消息可靠传递,可靠存储,不丢消息。
  • 高可用:支持集群,确保不会因为某个节点宕机导致服务不可用,当然也不能丢消息。
  • 高性能:具备足够好的性能,能够满足绝大多数场景的性能要求。

可供选择的消息队列

RabbitMQ

在这里插入图片描述

RabbitMQ使用Erlang语言编写,号称是世界上使用最广泛的开源消息队列之一,其支持灵活的配置,并且支持的语言是最多的。

但是其还存在很多的问题:

1.对消息堆积的支持并不好,在其理念里面,消息堆积本身是不正常的,作为使用者自己应该去避免

2.其性能是几个常用的性能中最差的,但是处理普遍的场景没啥问题,几万,数十万级别的

3.开发语言是Erlang语言,比较小众,语法还不一样,不容易看懂

RocketMQ

在这里插入图片描述

RocketMQ是阿里巴巴在2012年开源的消息队列产品,后来捐赠给Apache软件基金会,2017正式毕业,成为Apache的顶级项目。阿里内部也是使用RocketMQ作为支撑其业务的消息队列,经历过多次“双十一”考验,它的性能、稳定性和可靠性都是值得信赖的。作为优秀的国产消息队列,近年来越来越多的被国内众多大厂所使用。

如果所应用的非常在乎响应的时延,那么请选择RocketMQ。其性能比RabbitMQ高出来一个数量级。

Kafka

在这里插入图片描述

Kafka最早是由LinkedIn开发,目前也是Apache的顶级项目。其最初的设计目的是用于处理海量的日志。

Kafka与周边生态系统的兼容性是最好的没有之一,尤其是在大数据领域和流式计算领域,几乎所有的相关开源软件系统都会优先支持Kafka。

Kafka使用Scala和Java语言开发,设计上大量使用了批量和异步的思想,这种设计使得Kafka能做到超高的性能。Kafka的性能,尤其是异步收发的性能,是三者中最好的,但与RocketMQ并没有产生量级上的差异,大约每秒钟可以处理几十万条数据。

但是Kafka这种异步批量的设计带来的问题就是,它的同步收发消息的响应时延比较高,因为当客户端发送一条消息的时候,Kafka并不会立即发送出去,而是要等一会攒一批再发送,在它的Broker中,很多地方都会使用这种“先攒一波再一起处理”的设计。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka的时延反而会比较高。所以,Kafka不太适合在线业务场景。

总结:

如果对消息队列功能和性能都没有很高的要求,只需要一个开箱即用易于维护的产品,建议使用 RabbitMQ。

RocketMQ 对一致性的良好保证以及低延迟和金融级的稳定性,可以应用在电商各级业务调用的拆分中,比如在订单完成后通知用户,物流信息更新以后对订单状态的更新等。

  • 电商业务调用的拆分:RocketMQ 可以用于将电商系统中的不同业务模块解耦,通过消息队列传递各个模块之间的消息,实现业务流程的拆分和解耦,提高系统的可扩展性和灵活性。
  • 订单状态更新通知:RocketMQ 可以用于在订单完成后通知用户,以及当物流信息更新时更新订单状态。通过将通知消息发送到 RocketMQ,其他系统或服务可以订阅并相应地处理这些消息。

Kafka 可以在各类数据埋点中使用,比如电商营销的转化率日志收集和计算,另外,Kafka 的高性能使得特别它适合应用在各类监控、大数据分析等场景,或是你的应用场景大量使用了大数据、流计算相关的开源产品,那 Kafka 是最适合你的消息队列。

  • 电商营销转化率日志收集和计算:Kafka 可以用于收集电商网站的用户行为日志,例如点击、购买等,然后将这些日志提供给转化率计算引擎进行实时计算和分析,从而评估和优化营销活动的转化率。
  • 监控和大数据分析:Kafka 可以用作实时数据流的收集和传输工具,将来自各种监控系统、传感器、应用程序日志等的数据发送到大数据分析平台进行实时分析和处理。

消息队列的消费模式

Queue:数据结构,先进先出(FIFO,First - In - First - Out)的线性表,在后端插入数据,在前端删除数据。

队列模型

最初的一种消息模型:队列模型

生产者发消息就是入队操作,消费者收消息就是出队也就是删除操作,服务端存放消息的容器自然就称之为“队列”,需要严格有序。

在这里插入图片描述

如果存在多个消费者,此时每个消费者消费的都是部分数据,每个消费者加起来消费的数据,才是生产者生产的数据。

发布-订阅模型

在发布订阅模型中,消息的发送方称之为发布者,消息的接收方称之为订阅者,服务端存放消息的容器称之为主题

在这里插入图片描述

在发布订阅模式下,每个订阅了主题的订阅者,都可以完整的消费主题中的所有消息。

队列模式 VS 发布-订阅模式

  • 生产者就是发布者,消费者就是订阅者,队列就是另一个形式的主题。
  • 一份数据能不能被消费多次的问题,队列模式下每个消费者只能消费部分数据,发布-订阅模式下每个订阅者(消费者)可以消费完整的数据。

RabbitMQ的消息模型

RabbitMQ是少数依然坚持使用队列模型的产品之一。

在这里插入图片描述

如果同一份消息希望被多个消费者完整消费,配置Exchange将消息投递到多个队列中,每个队列中都存储了完整的消息数据。

其实是等同于变量的实现了“发布 - 订阅” 模型。

在这里插入图片描述

RocketMQ的消息模型

使用的消息模型是标准的“发布 - 订阅”模型。

在这里插入图片描述

当我们Broker中的topic下的queue收到消息之后,会向生产者发送确认的响应。如果消费者没有收到MQ的确认,此时会重新发送消息。

对于消费者来说,消费者收到消息并且完成自己的业务逻辑,会给MQ发送消费成功的确认,MQ收到确认后,认为该消息被消费成功了,否则它会给消费者重新发送该消息,直到收到消费成功的确认。

在Broker节点中,包括N个topic,每个topic包括多个queue,通过多个队列来实现多实例并行生产和消费。RocketMQ在队列层面保持消息的有序性而不是在Topic这一层。

消费组的概念(Consumer Group),多个消费者可以在逻辑上归为一个消费组。每个消费组都消费主题中的一份完整的消息,不同的消费组之间起到了隔离的效果,都是可以完整消费的,彼此的消费进度是不受影响的。同一个消息被Consumer Group1消费过,也会再给Consumer Group2进行消费。同一个组内的消费者是竞争关系,每个消费者消费的是组内的一部分数据。

因为消息会需要在不同的消费组进行多次消费,所以需要RocketMQ为每个消费组在每个队列上去维护一个消费位置(Offset)

在这里插入图片描述

Kafka的消息模型

在这里先说一个重大的区别:RocketMQ支持多个消费者消费同一个队列,而Kafka不支持多个消费者消费同一个分区。

在RocketMQ中,一个队列可以有多个消费者同时消费,这种模式称为"广播模式"。每个消费者都会接收到队列中的所有消息,实现了消息的高并发处理和负载均衡。

而在Kafka中,一个分区只能由一个消费者组中的一个消费者进行消费,这种模式称为"竞争消费模式"。不同的消费者组可以同时消费同一个主题的不同分区,但一个分区只能被一个消费者消费。这种设计模式适用于按照顺序处理消息或确保每条消息只被一个消费者处理的场景。

因此,RocketMQ的多个消费者消费一个队列的能力是它与Kafka的一个重要区别。

还有一个区别就是:在 Kafka 中,队列这个概念的名称不一样,Kafka 中对应的名称是“分区(Partition)”,含义和功能是没有任何区别的。

在这里插入图片描述

相关文章:

消息队列进阶-1.消息队列的应用场景与选型

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理🔥如果感觉博主的文章还不错的话,请&#x1f44…...

浅谈堆和栈内存以及编程语言

浅谈堆和栈内存以及编程语言 栈和堆C 和 C# 的区别:C#总结 编程语言C汇编语言(Assembly Language):机器语言(Machine Language): 拓展C#依赖注入(Dependency Injection)模…...

SpringBootWeb案例_01

Web后端开发_04 SpringBootWeb案例_01 原型展示 成品展示 准备工作 需求&环境搭建 需求说明: 完成tlias智能学习辅助系统的部门管理,员工管理 环境搭建 准备数据库表(dept、emp)创建springboot工程,引入对应…...

C语言数据结构-----栈和队列练习题(分析+代码)

前言 前面的博客写了如何实现栈和队列,下来我们来看一下队列和栈的相关习题。 链接: 栈和队列的实现 文章目录 前言1.用栈实现括号匹配2.用队列实现栈3.用栈实现队列4.设计循环队列 1.用栈实现括号匹配 此题最重要的就是数量匹配和顺序匹配。 用栈可以完美的做到…...

uniapp基础-教程之HBuilderX配置篇-01

uniapp教程之HBuilderX配置篇-01 为什么要做这个教程的梳理,主要用于自己学习和总结,利于增加自己的积累和记忆。首先下载HBuilderX,并保证你的软件在C盘进行运行,最好使用英文或者拼音,这个操作是为了保证软件的稳定…...

【备忘录】快速回忆ElasticSearch的CRUD

导引——第一条ElasticSearch语句 测试分词器 POST /_analyze {"text":"黑马程序员学习java太棒了","analyzer": "ik_smart" }概念 语法规则 HTTP_METHOD /index/_action/IDHTTP_METHOD 是 HTTP 请求的方法,常见的包括…...

影响PPC广告成本预算的因素,如何计算亚马逊PPC广告预算——站斧浏览器

亚马逊PPC,又称按点击付费(Pay Per Click),是一种只有用户点击你的广告时才会向你收费的模式。那么影响PPC广告成本预算的因素,如何计算亚马逊PPC广告预算? 影响PPC广告成本预算的因素 1、产品类别:不同类别的产品竞争程度不同&…...

Qt 信号和槽

目录 概念 代码 mainwindow.h me.h xiaohuang.h main.cc mainwindow.cc me.cc xianghuang.cc mainwindow.ui 自定义信号的要求和注意事项: 自定义槽的要求和注意事项: 概念 信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式(发布-订…...

Linux基本命令二

Linux基本命令二 1、head 命令 head ​ **作用:**用于查看文件的开头部分的内容,有一个常用的参数 -n 用于显示行数,默认为 10,即显示 10 行的内容 ​ **语法:**head [参数] [文件] ​ 命令参数: 参数…...

isbn api开放接口

接口地址:http://openapi.daohe168.com.cn/api/library/isbn/query?isbn9787115618085&appKeyd7c6c07a0a04ba4e65921e2f90726384 响应结果: { "success": true, "code": "200", "message": …...

助力企业实现更简单的数据库管理,ATOMDB 与 TDengine 完成兼容性互认

为加速数字化转型进程,当下越来越多的企业开始进行新一轮数据架构改造升级。在此过程中,全平台数据库管理客户端提供了一个集中管理和操作数据库的工具,提高了数据库管理的效率和便利性,减少了人工操作的复杂性和错误率&#xff0…...

如何通过低代码工具,提升运输行业的运营效率和服务质量

《中国数字货运发展报告》显示,2022年我国公路货运市场规模在5万亿元左右。其中,数字货运整体市场规模约为7000亿元,市场渗透率约为15%。而以小微企业为主的货运行业,却以小、散、乱的行业特征,承载着5万亿元左右的市场…...

Vue3中调用外部iframe链接方法

业务场景,点击某个按钮需要跳转到外部iframe的地址,但是需要在本项目内显示。以前项目中写过调用外部链接的功能,是有菜单的,但是这次是按钮,所以不能直接把地址配到菜单里。 实现方法:在本地路由文件里写个…...

Node——事件的监听与触发

Node.js是由事件驱动的,每个任务都可以当作一个事件来处理,本贴将对Node.js中的events模块及其中处理事件的类EventEmitter的使用进行详细讲解。 1、EventEmitter对象 在JavaScript中,通过事件可以处理许多用户的交互,比如鼠标…...

一个基于.NET Core开源、跨平台的仓储管理系统

前言 今天给大家推荐一个基于.NET Core开源、跨平台的仓储管理系统,数据库支持MSSQL/MySQL:ZEQP.WMS。 仓储管理系统介绍 仓储管理系统(Warehouse Management System,WMS)是一种用于管理和控制仓库操作的软件系统&…...

主机安全-WindowsLinux的SSH安全加固

信息安全相关 - 建设篇 第三章 主机安全-Linux的SSH安全加固 信息安全相关 - 建设篇系列文章回顾下章内容主机安全-Linux的SSH安全加固前言Windows openssh相关命令,安装openssh获取openssh命令Windows openssl相关命令,安装Git获取openssl命令修复 CVE-…...

pcie-2-rj45速度优化

背景: 目前用iperf3打流传输速率达不到要求,千兆实际要求跑到800M以上: 优化方案: 1.优化defconfig: 首先编译user版本验证看是否正常 debug版本关闭CONFIG_SLUB_DEBUG_ON宏控。 2.找FAE ,通过更换驱动,或者更新驱动来优化 3.绑定大核: 以8125网卡为例,udp…...

AWVS 使用方法归纳

1.首先确认扫描的网站,以本地的dvwa为例 2.在awvs中添加目标 输入的地址可以是域名也可以是ip,只要本机可以在浏览器访问的域名或ip即可 添加地址及描述之后,点击保存,就会展现出目标设置选项 business criticality译为业务关键…...

数据库基础入门 — SQL运算符

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 本…...

SELinux零知识学习二十九、SELinux策略语言之类型强制(14)

接前一篇文章:SELinux零知识学习二十八、SELinux策略语言之类型强制(13) 二、SELinux策略语言之类型强制 4. 类型规则 类型规则在创建客体或在运行过程中重新标记时指定其默认类型。在策略语言中定义了两个类型规则: type_transtition在域转换过程中标记行为发生时以及创…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

数据链路层的主要功能是什么

数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

【AI学习】三、AI算法中的向量

在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...