Home Note from Work
Post
Cancel

Note from Work

  1. Grafana 的数据显示会五分钟自动补全。当向 Prometheus 中插入某个时间戳的值时,其值会延续五分钟。

  2. K8S 中的 Sidecar 模式:通常情况下一个 Pod 只包含一个容器,但是 Sidecar 模式是指为主容器提供额外功能(例如监控) 从而将其他容器加入到同一个 Pod 中。再例如 Istio 实现 Sidecar 自动注入

  3. Federated cluster,联邦集群

  4. 限流算法:漏桶和令牌桶算法,漏桶算法处理请求的速度固定,突发请求过多时会丢弃;令牌桶算法除了限制数据的平均传输速率外,还要求允许某种程度的突发传输。

  5. 常见 HTTP 状态码:2XX,成功响应;3XX,重定向消息;4XX,客户端错误响应;5XX,服务端错误响应。

  6. 请求分为四部分:请求行,请求头,空行,请求正文(不一定有)。

  7. .gitignore 是在文件从工作区被 add 到暂存区时判断是否要被忽略,对于已经在暂存区的文件,不作判断。

数据结构

红黑树特性

  1. 节点非红即黑
  2. 根节点是黑色
  3. 叶子节点是黑色的空节点
  4. 红节点的子节点是黑节点
  5. 从根节点到空节点的每条路径,包含相同数量的黑色节点

常见NoSQL数据库类型

  1. 键值数据库:Redis
  2. 列式数据库:HBase, ClickHouse,适用于联机分析处理(OLAP)场景,数仓等
  3. 文档数据库:MongoDB, ElasticSearch
  4. 图数据库

Clickhouse:

  1. 不支持事务:因为面向列。不存在隔离级别。ClickHouse的定位是分析性数据库,而不是严格的关系型数据库
  2. 不支持高并发
  3. 可处理大量读请求,数据压缩的特性

分布式理论

两阶段协议

https://juejin.cn/post/6844903621495095309

三阶段协议

https://juejin.cn/post/6844903621495111688

FLP 不可能性原理

在网络可靠,存在节点失效(即便只有一个)的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性算法。对于允许节点失效情况下,纯粹异步系统无法确保一致性在有限时间内完成。

举例:三个人在不同房间,进行投票(投票结果是 0 或者 1)。三个人彼此可以通过电话进行沟通,但经常会有人时不时地睡着。比如某个时候,A 投票 0,B 投票 1,C 收到了两人的投票,然后 C 睡着了。A 和 B 则永远无法在有限时间内获知最终的结果。

CAP 定理

分布式系统只能交付以下三个所需特性中的两个特性:一致性、可用性和分区容错性。

  • C(Consistency):一致性,指的是所有客户端可以同时看到相同的数据。每当数据写入一个节点时,就必须立即将其转发或复制到系统中的所有其他节点
  • A(Availability):可用性,指的是可用性表示发出数据请求的任何客户端都会得到响应,即使一个或多个节点宕机。
  • P(Partition tolerance):分区容错性,指分区之间的通信可能失败。

一般来说,在分布式系统中不可避免会出现分区,因此认为 P 总是成立。因此若要实现一致性(CP),那么当出现分区问题时,就需要舍弃不一致的节点,即牺牲可用性。同理,若要实现可用性(AP),那么当出现分区问题时,就无法保证一致性。

Nacos集群默认支持 AP 原则(即不支持数据一致性,支持服务注册的临时实例),但也可切换至基于 Raft的 CP 原则(支持服务注册的永久实例)。

临时实例和持久化实例的区别:

  • 持久化实例健康检查后会被标记为不健康,而临时实例会直接从列表中删除。

MongoDB 是一种 CP 数据存储——它通过牺牲可用性、保持一致性来解决网络分区问题。

BASE 理论

  • Basically Available(基本可用),假设系统出现了不可预知的故障,但还是能用。
  • Soft State(软状态),允许系统在多个不同节点的数据副本存在数据延时。
  • Eventually Consistent(最终一致性),在软状态的一定期限过后,应达到数据的最终一致性。

核心思想是:即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

Raft 算法

可视化链接

三种角色:

  1. Leader,发送心跳包以维护自己的Leader状态
  2. Follower,响应Leader发送的心跳包
  3. Candidate,如果没有接收到Leader的心跳信号后,Follower会变成Candidate并向其他节点发送拉票信息

记时器:

  1. 选举超时时间(Follower拥有):若超时前没有收到心跳包,认为Leader下线,此时Follower会变成Candidate;但反之如果接收到心跳包,则重置计时器。
  2. 投票超时时间(Candidate拥有):若超时前没有得到半数以上的票数,则竞选失败;反之成功。
  3. 竞选等待超时时间(竞选失败的Follower拥有):竞选失败的Follower需要等待一段时间后才能重新竞选。

脑裂

由于某种原因(网络不稳定)使得主从集群一分为二,导致master或者leader节点的数量不为1(0或2)。

  • redis脑裂

master 机器突然脱离网络,使得 sentinel 集群无法感知到 master 的存在,会重新选举一个 master 节点。网络恢复后则会存在两个 master 节点。

  • zookeeper脑裂

脑裂可能出现平票的情况,从而无法选举出 leader。因此,zk 中建议节点数是奇数。

K8s

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维持容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的add-ons(扩展):

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

23种设计模式与六大原则

23种设计模式

  • 创建型
    1. 单例模式(Singleton)
      • 饿汉模式:类加载的时候就创建实例
      • 懒汉模式:只有当第一次使用的时候才创建实例
      • 双重校验锁:线程安全,实例需要用 volatile 修饰
    2. 原型模式(Prototype),能够复制已有对象,而又无需使代码依赖它们所属的类。例如 Cloneable 接口是立即可用的原型模式。
    3. 工厂方法模式(Factory Method),在父类中提供一个创建对象的方法, 允许子类决定实例化对象
    4. 抽象工厂模式(Abstract Factory),定义了用于创建不同产品的接口, 但将实际的创建工作留给了具体工厂类。 每个工厂类型都对应一个特定的产品变体。
    5. 建造者模式(Builder),分步骤创建复杂对象。
  • 行为型
    1. 模板方法模式(Template Method),它在基类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。
    2. 责任链模式(Chain of Responsibility),它让多个处理器(对象节点)按顺序处理该请求,直到其中某个处理成功为止,例如检查商品模块,需要先检查商品合法性,再检查商品可见性等等。
    3. 命令模式(Command)
    4. 迭代器模式(Iterator),能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
    5. 中介者模式(Mediator)
    6. 备忘录模式(Memeoto)
    7. 观察者模式(Observer)
    8. 状态模式(State)
    9. 策略模式(Strategy),规定每个策略的不同方法,只需选择不同的策略即可执行不同的方法,例如数字人项目中 Provider 的选择(1:AiLab,2:Creatify,3:IC,4:IC-NEW)
    10. 访问者模式(Visitor)
    11. 解释器模式(Interpreter)
  • 结构型
    1. 适配器模式(Adaptor)
    2. 桥接模式(Bridge)
    3. 组合模式(Composite)
    4. 装饰模式(Decorator)
    5. 外观模式(Facade),为复杂系统、程序库或框架提供一个简单的接口。通常作用于整个对象子系统上。
    6. 享元模式(Flyweight),共享多个对象的部分状态将内存消耗最小化。
    7. 代理模式(Proxy),例如动态代理

六大原则

  1. 开闭原则,对扩展开放,对修改关闭。
  2. 单一职责原则,顾名思义,一个类的职责只有有一个。
  3. 里氏替换原则,子类可以扩展父类的功能,但不能改变父类原有的功能。
  4. 依赖倒转原则,依赖于抽象,不能依赖于具体实现(面向接口编程)。
  5. 接口隔离原则,类之间的依赖关系应该建立在最小的接口上。
  6. 迪米特原则,一个软件实体应当尽可能少的与其他实体发生相互作用。

分布式事务 Seata

分两阶段提交

  1. TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚。
  2. TM (Transaction Manager) - 事务管理器:定义全局事务的范围:开始全局事务、提交或回滚全局事务。
  3. RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

执行流程:

  1. TM 向 TC 请求发起(Begin)、提交(Commit)、回滚(Rollback)等全局事务。
  2. TM 把代表全局事务的XID绑定到分支事务上。
  3. RM 向 TC 注册,把分支事务关联到XID代表的全局事务中。
  4. RM 把分支事务的执行结果上报给 TC。
  5. TC 发送分支提交(Branch Commit)或分支回滚(Branch Rollback)命令给RM。

四大模式

  1. AT模式,能适用于大部分事务情况。
  2. XA模式
  3. SAGA模式,核心思想是将长事务拆分成多个本地短事务。
  4. TCC模式,核心思想是针对每个操作都要注册一个与其对应的确认和补偿操作。

其他分布式事务解决方案:

  1. 基于 RocketMQ 的消息事务
  2. 二阶段提交
  3. 三阶段提交,CanCommit、PreCommit、DoCommit三阶段

ZooKeeper(CP)

使用 ZAB 协议,包括两种运行模式:

  1. 消息广播(Leader 正常运行),所有事务请求由单一主进程处理,Leader 转换为事务 Proposal 并广播分发给 Follower,Leader 等待 Follower 的反馈,超过半数的 Follower 反馈消息后,Leader 再发送 Commit 消息提交事务 Proposal。

  2. 崩溃恢复(Leader 不可用时),新选举产生的 Leader 与过半的 Follower 进行同步,使数据一致,同步后进入消息广播模式。

主要服务于分布式系统,可以用ZooKeeper来做:统一配置管理、统一命名服务、分布式锁、集群管理,用来解决分布式集群中应用系统的一致性问题,构建 ZooKeeper 集群时使用的服务器最好是奇数台。其设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

数据结构:Znode节点,与Unix文件系统类似,通过路径来标识,例如 /home/app,Znode节点又分为两种类型:临时节点、持久节点、临时顺序节点、持久顺序节点。客户端和服务端断开连接后,临时节点会自动删除但持久节点不会。分布式锁使用的是临时节点

Watcher 监听器:节点的数据发生变化后会通知到节点的监听器。

基本命令:

  • create : 在树中的某个位置创建一个节点
  • delete : 删除一个节点存在:测试节点是否存在于某个位置
  • get data : 从节点读取数据
  • set data: 将数据写入节点
  • get children : 检索节点的子节点列表
  • sync : 等待数据被传播

实现分布式锁原理:判断能否创建临时节点,如果不能则监听父节点(非公平锁)或上一个节点(公平锁),任务执行完成后释放该节点并通知所有监听的节点。

实现注册中心原理:初始化时 Provider 先向目录写入 URL 地址,Consumer 订阅相同目录的 URL 地址和自己的 URL 地址,监控中心订阅 Provider 和 Consumer 的 URL 地址;Consumer 在第一次调用服务时,会通过注册中心找到相应的服务的IP地址列表,并缓存到本地,以供后续使用;当 Provider 下线时,会在列表中移除 URL 并将新的 URL 地址发送给 Consumer 并缓存至本地,服务上线也是一样的。

与 Nacos 的区别:

Nacos 是 AP 的,保证可用性,每个节点都是平等的,若干个节点 crash 后不会影响正常节点,但查到的信息不一定是最新的。ZK 在 crash 后进行 leader 选举,期间是不可用的。

微服务框架:Dubbo

底层基于 Netty 的 NIO 框架,基于 TCP 协议传输

四种负载均衡策略

支持服务端服务级别、服务端方法级别、客户端服务级别、客户端方法级别的负载均衡配置。还可以拓展负载均衡算法。

  1. 随机负载均衡,默认策略
  2. 轮询负载均衡
  3. 最少活跃调用数,每个 Provider 都有一个计数器,开始调用则计数器加一,结束调用计数器减一。原则是将请求分配给处理速度快的 Provider。
  4. 一致性哈希负载均衡

HTTPS 如何保证可靠传输

TLS 协议:

  1. 对称加密/非对称加密
  2. 数字证书
  3. 三次握手/四次挥手

TLS 的 rsa 握手过程,存在什么安全隐患,怎么解决的?

  • 安全隐患:不支持前向保密。如果私钥泄露了,所有密文都会被破解
  • 解决方案:密钥协商算法

HTTPS 绝对安全吗

NO,可以通过中间人攻击的方式,即所有请求先发送给第三方(中间人),返回中间人的证书,后续的请求/响应都通过中间人进行转发。

HTTP版本的演变

HTTP/1.0

  • 无状态:服务器不追踪不记录请求过的状态
  • 无连接:每次请求要建立连接,无法复用连接;在前一个请求响应到达之后下一个请求才能发送,如果前一个阻塞,后面的请求也被阻塞

HTTP/1.1

默认浏览器对同一域名的并发请求限制为 6 - 8 个。

  • 长连接:默认保持长连接,数据传输完成后只要不断开连接,就可以继续传输数据
  • 管道化:基于上面长连接的基础,可以不等第一个请求响应继续发送后面的请求,但响应的顺序还是按照请求的顺序返回
  • 缓存处理:新增字段cache-control
  • 断点传输:在上传/下载资源时,如果资源过大,将其分割为多个部分,分别上传/下载

HTTP/2

  • 二进制分帧传输:更方便头部,只传输差异部分
  • 多路复用:同一服务下只需要用一个连接,节省了连接
  • 头部压缩:合并同时发出请求的相同部分
  • 服务器推送:一次客户端请求服务端可以多次响应

HTTP/3

基于谷歌的QUIC,底层使用udp代码tcp协议,解决了队头阻塞问题,同样无需握手,性能大大地提升,默认使用tls加密。

进程和线程

进程拥有的资源

  1. 进程控制块
  2. 文件描述符
  3. 网络连接
  4. 设备

区别:

  1. 进程是系统资源分配的最小单位,实现了操作系统的并发;线程是CPU调度的最小单位,实现了进程内部的并发。
  2. 进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。
  3. 进程切换的开销远大于线程切换的开销。
  4. 进程之间不会相互影响,但线程挂掉会影响整个进程。

进程间通信方式:

  1. 管道
  2. 信号量
  3. 消息队列
  4. 共享内存
  5. 套接字,也可以用于不同主机之间进程的通信

线程间通信方式:

  1. 共享内存,比如 volatile 保证内存的可见性。
  2. 消息传递,比如 wait/notify/notifyAll 等待通知方式和 join 方式。
  3. 管道流

用户态和内核态

为什么要有这两个状态?保护机制,防止用户误操作或恶意破坏系统

用户态

  1. 是用户进程/线程所在的区域,主要用于执行用户程序
  2. 运行的代码会受到CPU的很多检查,不能直接访问内核数据
  3. 只拥有受限的权限
  4. 只能响应部分中断请求
  5. 只能访问受限的地址空间

内核态

  1. 是内核进程/线程所在的区域,主要用于执行操作系统程序,硬件交互
  2. 运行的代码不受任何限制,可以执行任意指令
  3. 拥有最高权限
  4. 可以响应所有中断请求
  5. 可以访问所有内存空间

用户态切换到内核态

  1. 系统调用(主动)。操作系统在执行用户程序的时候主要工作在用户态,当执行没有权限的任务时,才切换到内核态。
  2. 异常(被动)。执行用户程序出现异常时,会从用户态切换到内核态处理异常
  3. 外围设备中断(被动)。中断发生时,如果中断之前在运行用户态的程序,那么会切换至内核态处理中断。

服务注册与发现

如果自己实现服务注册与发现,需要考虑以下三点:

  1. Register, 服务启动时候进行注册
  2. Query, 查询已注册服务信息
  3. Healthy Check, 确认服务状态是否健康

实现方案:

  1. Eureka,AP
  2. ZooKeeper,CP,Paxos 算法
  3. Consul,CP,Raft 算法
  4. Etcd,CP,Raft 算法

Paxos 和 Raft 算法都属于一致性算法,所以是保证 CP

实际上,作为一个注册中心来说,保证 AP 更加重要,即可用性。

两种模式

  1. 客户端发现模式,首先要进行的是到服务注册中心获取服务列表,然后再根据调用端本地的负载均衡策略,进行服务调用。
  2. 服务端发现模式,调用方直接向服务注册中心进行请求,服务注册中心再通过自身负载均衡策略,对微服务进行调用。这个模式下,调用方不需要在自身节点维护服务发现逻辑以及服务注册信息。

常见的负载均衡

  1. 轮询,按照请求的顺序轮流分配到不同的服务器,循环往复。
  2. 加权轮询,给不同的服务器分配不同的权重,根据权重比例来决定分配请求的数量。
  3. 最小连接数
  4. 最短响应时间
  5. IP哈希

RPC/HTTP

与 HTTP 的对比,RPC 使用二进制传输,传输效率高(HTTP额外空间开销大,包含大量元数据,头字段等),但通用性不如 HTTP 协议

核心

  1. 消息协议:以何种方式打包编码和拆包解码
  2. 传输控制:主要有HTTP传输和TCP传输,鉴于TCP传输的可靠性,RPC的传输一般使用TCP作为传输协议

工作流程

  1. 客户端(Client)以本地方法调用服务
  2. 客户端存根(Client Stub)收到调用后把方法、参数等内容打包成特定格式、能进行网络传输的消息体(Marshalling)
  3. 客户端存根找到服务地址,发送给服务端(这个过程可以基于TCP也可以基于HTTP)
  4. 服务端存根(Server Stub)收到消息后拆包解码(Unmarshalling)
  5. 服务端存根根据方法名和参数进行本地调用服务
  6. 服务端(Server)本地执行后把结果返回给服务端存根
  7. 服务端存根把结果打包发送给客户端存根
  8. 客户端存根接收到消息进行解码
  9. 客户端得到最终结果

实现方式

  1. 基于 http
  2. 基于 tcp(常见)

计算机网络

TCP/UDP 可以使用同一个端口吗

可以。传输层有两个传输协议分别是 TCP 和 UDP,在内核中是两个完全独立的软件模块。可以在 IP 包头的协议号字段判断出 TCP 还是 UDP

TCP 三次握手

为什么三次握手

因为三次握手才能保证双方具有接收和发送的能力,并且防止重复建立历史连接。

为什么四次挥手

本质原因是 TCP 是全双工通信,客户端确认没有数据发送后,发出结束报文,此时服务端返回确认后,服务端也不会接收客户端数据。但是此时服务端可能还有数据没有传输完,客户端还是可以接收数据。

如果挥手过程中「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手

DNS使用TCP还是UDP

DNS 在进行区域传输的时候使用 TCP,其他情况使用 UDP。

区域传输:是指DNS主从服务器之间的数据同步,保证数据的一致性,传送会利用DNS域,所以就称为DNS区域传送。

TCP 保证可靠传输

  1. 序列号
  2. 连接建立:三次握手四次挥手
  3. 头部检验和
  4. 确认应答
  5. 超时重传
  6. 拥塞控制:四种算法
    1. 慢启动
    2. 拥塞避免
    3. 拥塞发生
    4. 快速恢复
  7. 流量控制:滑动窗口实现

OSI 七层模型和 TCP/IP 四层模型

  1. 应用层:HTTP,DNS,FTP,WebSocket;网关
    1. 应用层
    2. 表示层
    3. 会话层
  2. 传输层:TCP,UDP;网关
  3. 网络层:IP(在TCP/IP模型中,ARP属于网络层);路由器
  4. 网络接口层
    1. 数据链路层:ARP;网桥,交换机
    2. 物理层:网卡;中继器,集线器

架构

在高并发环境下,服务之间的依赖关系导致调用失败,解决的方式通常是: 限流->熔断->隔离->降级, 其目的是防止雪崩效应。

死锁

四个条件:

  1. 互斥
  2. 请求和保持
  3. 不可剥夺
  4. 循环等待

一致性哈希

一致性哈希是指将「存储节点」和「数据」都映射到一个首尾相连的哈希环(固定大小)上。数据存储在哈希值通过顺时针找到的第一个节点。

优势

一致性哈希算法是对 2^32 取模,是一个固定的值;而普通哈希表的长度是由节点数决定的。

  • 普通哈希函数,如果节点数量发生了变化(对系统进行扩容缩容的时候),大部分改变了映射关系,因此需要迁移大量的数据。
  • 一致性哈希算法,如果节点数量发生了变化,只影响该节点顺时针相邻的后继节点。

虚拟节点的引入

一致性哈希算法并不保证节点能够在哈希环上分布均匀,因此引入均匀分布的虚拟节点,建立真实节点和虚拟节点的映射关系。

IO

  1. 同步
    1. 同步阻塞IO
    2. 同步非阻塞IO
    3. IO多路复用
    4. 信号驱动IO
  2. 异步
    1. 异步IO

虚拟内存

虚拟内存是一种计算机技术,它允许系统将一部分硬盘空间当作RAM(随机存取存储器)使用。当物理内存不足以支持正在运行的应用程序时,系统会将不常用的数据移动至磁盘中。虚拟内存为每个进程提供了一个一致的、私有的地址空间

32位/64位操作系统的区别

32位/64位表示CPU可以处理最大位数,一次性的运算量不一样,寻址能力也不同。

域名解析流程

  1. 检查缓存
    1. 浏览器缓存
    2. 操作系统缓存
    3. 本地 hosts 文件
  2. 使用递归查询向本地域名服务器查询
  3. 使用迭代查询向跟服务器查询
    1. 根域名服务器(.)
    2. 顶级域名服务器(.com)
    3. 二级域名服务器(google.com)

排查 CPU 占用过高和内存溢出的问题

Java

CPU 占用排查:使用 toptop -Hp xxx 命令定位占用率最高的进程和该进程的线程 内存占用排查:jstackjmap 打印出堆栈信息, jstat 查看垃圾回收的情况

  • Jstat 可以查看新生代的两个S0、s1区、Eden区,以及老年代的内存使用率,还有young gc以及full gc的次数。
  • Jmap 可以查看当前堆中所有每个类的实例数量和内存占用,也可以 dump 内存快照,再由 VituralVM 或 MAT 软件可视化查看。

Go

使用 pprof 工具,可以查看 CPU 占用、排查内存泄漏、协程泄漏等。

互斥锁和自旋锁

  1. 互斥锁是一种阻塞锁,获取不到锁的时候,线程会被挂起。
  2. 自旋锁是一种非阻塞锁,获取不到锁的时候,线程不会被挂起,而且不断去获取,消耗 CPU 资源。

缓存 IO,直接 IO,裸 IO

  • 缓存IO:读数据时先从内核空间的缓冲区读,如果没有则从磁盘中读并缓存到缓冲区;写数据将用户空间的数据复制到内核空间的缓冲区,并标记为脏页,操作系统后台将脏页写入磁盘中,一般用于频繁读写的小文件;
  • 直接IO:直接读写文件,而不经过内核缓冲区,目的是减少一次内核缓冲区到用户程序缓存的数据复制,一般用于不需要频繁读写的大文件;
  • 裸IO:绕过文件系统,直接读写磁盘块设备数据,一般用于数据库;

Base64 和 Base62 的区别

编码

  1. Base64:26 个大写字母 + 26 个小写字母 + 10 个数字 + + + /;并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的「/」和「+」字符变为形如「%XX」的形式。
  2. Base62:26 个大写字母 + 26 个小写字母 + 10 个数字。

实现

  1. Base64:将输入字符串按字节切分,取得每个字节对应的二进制值(若不足 8 比特则高位补 0),然后将这些二进制数值串联起来,再按照 6 比特一组进行切分(因为 2^6=64),最后一组若不足 6 比特则末尾补 0。若原字节序列数据长度不是 3 的倍数时且剩下 1 个输入数据,则在编码结果后加 2 个 =;若剩下 2 个输入数据,则在编码结果后加 1 个 =。将每组二进制值转换成十进制,然后找到对应的符号并串联起来就是 Base64 编码结果。
  2. Base62:将输入字符串哈希后转成长整型,再用62进制编码成Base62格式。
This post is licensed under CC BY 4.0 by the author.

Kafka vs RocketMQ

Go 语言学习