1000亿数据、30W级qps如何架构?来一个天花板案例
1000亿级存储、30W级qps系统如何架构?来一个天花板案例
说在前面
在尼恩的(50+)读者社群中,经常遇到一个 非常、非常高频的一个架构面试题,类似如下:
- 千万级数据,如何做系统架构?
- 亿级数据,如何做做系统架构?
- 千万级流量,如何做系统架构?
- 亿级流量,如何做做系统架构?
- 高并发系统,如何架构?
**最近,有个小伙伴阿里三面,又遇到了这个问题。**这类问题,非常复杂,稍微回答不好,面试就挂掉。
尼恩一直想梳理一个教科书式的答案。
这里,尼恩结合B站的行业案例《B站千亿级点赞系统服务架构设计》,从 面试维度,对这个方案进行二次重构和梳理,然后把梳理的结果,作为以上面试题的参考答案,并收入咱们的《尼恩Java面试宝典 PDF》 V54版本,供后面的小伙伴参考,大家一定好好看看这个教科书级别的答案。
原始方案的作者,是芦文超,是哔哩哔哩资深开发工程师。原始的文章请参见b站的公众号, pdf版收藏在尼恩的3高行业案例集合中,也可以找尼恩获取。
下面的内容,并不是原文,而是尼恩是结合自己的3高架构笔记,以及尼恩的3高架构知识体系(3高架构宇宙)做的二次创作。
注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请从这里获取:码云
点赞场景的业务分析
做系统架构,首先要需求分析。
点赞的业务,已经足够的简单,极致的简要
需求1:视频的点赞数

需求2:UP主维度的总获赞数

需求3:个人的点赞记录

需求N:细分的需求比较多…
大家自行脑补,当然,也可以来尼恩的技术自由社群 (50+)里边交流。
数据规模、流量规模分析
做系统架构,其次,要确定 数据规模、流量规模, 为啥呢?
不同的体量,架构的方式、方法、方案,都完全不一样。
按照尼恩的3高架构笔记中的分析套路,接下来,对这个案例的数据规模、流量规模进行 梳理和分析。
数据规模:千亿级别
流量规模:
读流量:30W QPS , 全站点赞状态查询、点赞数查询等【读流量】超过300k,
写流量:1.5W QPS ,点赞、点踩等【写流量】超过15K

大流量、大数据场景下点赞中台化诉求
点赞功能,在中台化之前,是分散的。各大业务模块,都有点赞功能的存在,如以下模块:
稿件、视频、动态、专栏、评论、弹幕、等等

以 “稿件” 为例,点赞服务需要提供
- 对某个稿件点赞(取消点赞)、点踩(取消点踩)
- 查询是否对 单个 或者 一批稿件 点过赞(踩) - 即点赞状态查询
- 查询某个稿件的点赞数
- 查询某个用户的点赞列表
- 查询某个稿件的点赞人列表
- 查询用户收到的总点赞数
大流量、大数据场景下,需要进行中台化、平台化
- 进行业务聚合,提供多种实体维度数据查询、数据分析的能力
- 点赞作为一个与社区实体共存的服务,需要提供很强的容灾能力
- 提供业务快速接入的能力(配置级别)
- 数据存储上(缓存、DB),具备数据隔离存储的能力(多租户)
中台化 之后的架构图如下

从此,各大业务模块,业务子系统,再也不用担心点赞的 海量数据问题, 巨量的流量问题, 点赞服务的不可用的问题。
这些问题,都交给中台解决了。各大业务模块,业务子系统,直接使用接口就行。
B站点赞中台的整体架构
B站架构师给出的架构图
下面是哔哩哔哩资深开发工程师 芦文超, 给出的系统架构图

整个点赞服务的中台可以分为五个部分
- 流量路由层(决定流量应该去往哪个机房)
- 业务网关层(统一鉴权、反黑灰产等统一流量筛选)
- 点赞服务(thumbup-service),提供统一的RPC接口
- 点赞异步任务(thumbup-job)
- 数据层(db、kv、redis)
上的B站小伙伴的分层方案,从架构的维度不是太好理解,接下来按照尼恩的3高架构笔记中的分析套路,给大家做进一步的梳理。
分层架构的二次梳理
按照尼恩的3高架构笔记中的分析套路,接下来,对这个案例的分层架构:

接下来,按照尼恩的3高架构理论,一 层一 层来,进行庖丁解牛。
对这个B站千亿级点赞系统服务架构设计,使之成为大家的超级学习案例。
B站点赞中台的接入层架构
架构和语言无关,b站使用go语言开发, 尼恩的他的小伙伴们, 更喜欢使用 Java。下面从Java架构的角度进行分析。
回顾一下尼恩的3高架构笔记
客户端的请求进来会先到SLB(负载均衡),然后到内部的网关,通过网关再分发到具体的业务服务。
业务服务会依赖Redis、Mysql、 MQ、Nacos等中间件。

B站点赞中心做异地多活,在不同地区有不同的机房,他们的架构中,有两个机房。
所以,他们的接入层的效果如下图所示:

流量路由层
用户的请求,从客户端发出,这个用户的请求该到哪个机房,这是 流量路由层 决定的。
首先,用户需要尽量路由到同一个 机房。
为什么呢?虽然服务之间的数据,是没有依赖的,但是服务内部依赖的存储是有状态的。不同的机房之间,虽然有数据同步,但是,毕竟会有延迟。如果用户修改了数据之后,再一查,查不到,感觉非常困惑。
如何 路由到同一个 机房?
首先,使用普通dns是不行的,普通的dns,域名会随机解析到不同的机房中。
一个综合方案:智能DNS + DLB流量网关
第一个维度是智能DNS,这个具体这里不做展开,请参见 尼恩的3高架构笔记。
但是智能DNS也不是万能的,需要接入层进行流量矫正。
所以针对同一个用户,尽可能在一个机房内完成业务闭环。
流量路由层 为了解决流量调度的问题,可以基于OpenResty二次开发出了DLB流量网关,DLB会对接多活控制中心,能够知道当前访问的用户是属于哪个机房,如果用户不属于当前机房,DLB会直接将请求路由到该用户所属机房内的DLB。

如果每次都随机到固定的机房,再通过DLB去校正,必然会存在跨机房请求,耗时加长。
所以在这块也是结合客户端做了一些优化,在DLB校正请求后,可以将用户对应的机房IP直接通过Header响应给客户端。
这样下次请求的时候,客户端就可以直接通过这个IP访问。
如果用户当前访问的机房挂了,客户端需要降级成之前的域名访问方式,通过DNS解析到存活的机房。
接入层的业务网关
架构和语言无关。
b站使用go语言开发, 尼恩的他的小伙伴们, 更喜欢使用 Java。
下面从 Java的角度进行架构分析。
业务网关包括的功能:统一鉴权、反黑灰产等统一流量筛选
接入层功能之一:统一鉴权
这一层,从架构的维度来说,可以在SpringCloud gateway 中, 使用 过滤器进行 统一鉴权
具体请参见尼恩 的10Wqps推送中台架构与实操,里边有详细的介绍
接入层功能2:流量筛选
黑灰产,又称非法产业、非法企业或非法经济
所谓网络黑灰产,指的是电信诈骗、钓鱼网站、木马病毒、黑客勒索等利用网络开展违法犯罪活动的行为。稍有不同的是,“黑产”指的是直接触犯国家法律的网络犯罪,“灰产”则是游走在法律边缘,往往为“黑产”提供辅助的争议行为。
流量筛选这一层,从架构的维度来说, 可以在SpringCloud gateway 中, 使用 过滤器进行 风险ip、风险用户id的 动态探测,拦截。
动态探测可以使用成熟的动态探讨框架,如jd的hotkey, 也可以使用滑动窗口算法,实现类似的动态探测组件。
具体请参见尼恩 的100Wqps三级缓存架构与实操,里边有详细的介绍
B站点赞中台的服务层架构
架构和语言无关。
b站使用go语言开发, 尼恩的他的小伙伴们, 更喜欢使用 Java。下面从Java架构的角度进行分析B站点赞中台的服务层架构。
点赞的业务比较简单,性能也可以很高。但是,之后的入库的操作,性能低。
所以,采用消息队列进行异步消峰解耦。

实际上,这里整体用的是异步+批量的架构,异步是一种即为重要的架构模式,关于20种异步的方式,请参见尼恩的深度文章:20种异步,你知道几种? 含协程
B站点赞中台的服务层架构,细分为两层:
- 点赞服务层
- 异步任务层
点赞服务层(thumbup-service)
点赞服务层接收到用户的点赞请求,完成点赞的业务计算:
- 点赞数
- 点赞状态
- 点赞列表
- 等等
具体的功能,参考下图

异步任务层(thumbup-job)
异步任务主要作为点赞数据写入、刷新缓存、为下游其他服务发送点赞、点赞数消息等功能
- 点赞数据写入:含用户行为数据(点赞、点踩、取消等)的写入
- 缓存刷新:点赞状态缓存、点赞列表缓存、点赞计数缓存
- 同步点赞消息
- 点赞事件异步消息、点赞计数异步消息
首先是最重要的用户行为数据(点赞、点踩、取消等)的写入。
搭配对数据库的限流组件以及消费速度监控,保证数据的写入不超过数据库的负荷的同时,也不会出现数据堆积造成的C数据端查询延迟问题。

超高流量压力的异步批量处理
超高的全局流量压力:
超高并发读:全站点赞状态查询、点赞数查询等【读流量】超过300k,
超高并发写:点赞、点踩等【写流量】超过15K
采用的策略是: 异步写入+批量写入
异步写入
同时数据库的写入我们也做了全面的异步化处理,保证了数据库能以合理的速率处理写入请求。
批量写入(聚合写入)
针对写流量,为了保证数据写入性能,B站在写入【点赞数】数据的时候,在内存中做了部分聚合写入,比如聚合10s内的点赞数,一次性写入。
如此可大量减少数据库的IO次数。
尼恩提示:异步写入+批量写入,是尼恩3高架构系统中,一种非常核心的模式,Netty源码,Hotkey源码,都在大量使用,具体请参见尼恩3高架构笔记。
B站点赞中台的数据层架构
架构和语言无关,b站使用go语言开发, 尼恩的他的小伙伴们, 更喜欢使用 Java。下面从Java架构的角度进行数据层架构分析。

二级缓存架构

二级缓存:分布式Cache 缓存架构
缓存层Cache:点赞作为一个高流量的服务,缓存的设立肯定是必不可少的。
点赞系统主要使用的是CacheAside模式。
有关 CacheAside模式, 具体请参见尼恩的 100Wqps 三级缓存组件架构和实操。
这一层缓存主要基于Redis缓存:以点赞数和用户点赞列表为例,进行介绍
实体的点赞数的缓存设计
用业务ID和该业务下的实体ID作为缓存的Key,并将点赞数与点踩数拼接起来存储以及更新

key-value = count:patten:{business_id}:{message_id} - {likes},{disLikes}
business_id 代表 业务id
message_id 代表 实体 id
用户的点赞列表缓存设计
一个用户,在一个业务下的 所有点赞 的列表

key = user:likes:patten:{mid}:{business_id} value = zset , member(messageID)-score(likeTimestamp)
key为 mid 与业务ID , mid 代表用户 , business_id 代表业务id
value则是一个ZSet,member为被点赞的实体ID,score为点赞的时间。
当改业务下某用户有新的点赞操作的时候,被点赞的实体则会通过 zadd的方式,把最新的点赞记录加入到该ZSet里面来
为了维持用户点赞列表的长度(不至于无限扩张),需要在每一次加入新的点赞记录的时候,按照固定长度裁剪用户的点赞记录缓存。
该设计也就代表用户的点赞记录在缓存中是有限制长度的,超过该长度的数据请求需要回源DB查询
一级本地存储架构
LocalCache - 本地缓存
本地缓存的建立,目的是为了应对缓存热点问题。 本地缓存主要解决缓存击穿的问题。
在Java应用中,本地缓存建议选用命中率最高的caffeine组件, 其内存淘汰算法 wtiny-lfu,集合了 lrf与lfu的精华,非常牛掰。
具体,请参考尼恩的100Wqps三级缓存组件的介绍,里边对caffeine的架构和源码和算法,做了穿透式的解读。
热点探测:
热门事件、稿件等带来的系统热点问题,包括DB热点、缓存热点
当一个稿件成为超级热门的时候,大量的流量就会涌入到存储的单个分片上,造成读写热点问题。
此时需要有热点探测机制来识别该热点,并将数据缓存至本地,并设置合理的TTL。
例如,UP主 【杰威尔音乐】发布第一个稿件的时候就是一次典型热点事件。
所以,本地缓存一般要结合热点探讨框架使用,
有关热点探讨框架,请参考尼恩的100Wqps三级缓存组件的介绍。
二级DB架构

在尼恩的架构体系中, 一般是 结构化DB+NOSql结合的二级架构模式:
- 结构化DB , 为业务计算提供数据支撑, 如mysql、tidb 等等
- NOSql DB, 提供历史数据支撑,全量数据支撑, 大数据计算支撑, 如hbase,mongdb 等
后面尼恩会为大家介绍左手云原生,右手大数据,就是基于上面的架构系统。
B站的二级DB架构,也是这种经典的二级架构。
结构化数据存储
基本数据模型:
- 点赞记录表:记录用户在什么时间对什么实体进行了什么类型的操作(是赞还是踩,是取消点赞还是取消点踩)等
- 点赞计数表:记录被点赞实体的累计点赞(踩)数量
①、第一层存储:DB层 - (TiDB)
点赞系统中最为重要的就是点赞记录表(likes)和点赞计数表(counts),负责整体数据的持久化保存,以及提供缓存失效时的回源查询能力。
表1:点赞记录表 - likes :
字段:
用户Mid、被点赞的实体ID(messageID)、点赞来源、时间 等等,
索引:
联合索引(Mid、messageID ) ,用于满足业务请求。
表2:点赞数表 - counts :
字段:
业务ID(BusinessID) 、实体ID(messageID) 、实体的点赞数、点踩数等。
索引:
以业务ID(BusinessID)+实体ID(messageID)为主键,
并且按照messageID维度建立满足业务查询的索引。
结构化DB的分库分表方案
由于DB采用的是分布式数据库TiDB,所以对业务上无需考虑分库分表的操作
如果选用mysql,可以使用shardingjdbc 进行客户端分片的计算,这种方案,非常普遍。
NOSql解决全量数据的数据存储压力
点赞数据的规模:超过千亿级别
如何高效的利用存储介质存放这些数据才能既满足业务需求,也能最大程度节省成本,也是一个点赞服务正在努力改造的工程 - KV化存储
针对TIDB海量历史数据的迁移归档
迁移归档的原因(初衷),是为了减少TIDB的存储容量,节约成本的同时也多了一层存储,可以作为灾备数据。
作为一个典型的大流量基础服务,点赞的存储架构需要最大程度上满足两个点
①、最大的可靠性:满足业务读写需求的同时具备最大的可靠性
②、最小化存储成本: 选择合适的存储介质与数据存储形态,最小化存储成本
从以上两点出发,考虑到KV数据在业务查询以及性能上都更契合点赞的业务形态,选用 TaiShan(B站自研的KV数据库) 作为NoSql的存储方案。
数据一致性架构
采用的是非常经典的 cannal+binlog的架构,具体如下:

有关 cannal+binlog的架构和实操,请参考尼恩的100Wqps三级缓存组件的介绍。
建议大家做一下实操。尤其是高可用cannal实操。
容灾架构:
作为被用户强感知的站内功能,需要考虑到各种情况下的系统容灾。例如当:
1、存储不可用
- 例如当DB不可用时,需要依托缓存尽可能提供服务。
- 同理当缓存不可用时,DB也需要保证自己不宕机的情况下尽可能提供服务。
2、消息队列不可用
- 当消息队列不可用时,依托B站自研的railgun,通过RPC调用的方式自动降级
3、机房灾难
- 切换机房, 通过 流量路由层实现
4、数据同步容灾
比如点赞就遇到过因为cannal+binlog的数据同步问题(断流、延迟)导致的点赞计数同步延迟问题。
5、服务层的容灾和降级
1 存储(db、redis等)的容灾设计(同城多活)
作为面对C端流量的直接接口,在提供服务的同时,需要思考在面对各种未知或者可预知的灾难时,如何尽可能提供服务
在DB的设计上,点赞服务有两地机房互为灾备,设计专用的proxy代理层,db-proxy(sidecar), 业务通过db-proxy(sidecar)访问 redis和db。
db-proxy(sidecar)为了方便业务访问,使用的是 sidecar 模式,有关sidecar 模式的内容,具体请参见尼恩的左手云原生、右手大数据笔记。
正常情况下,机房1承载所有写流量与部分读流量,机房2承载部分读流量。
当DB发生故障时,通过db-proxy(sidecar)的切换可以将读写流量切换至备份机房继续提供服务。


在缓存(Redis)上,点赞服务也拥有两套处于不同机房的集群,并且通过异步任务消费TiDB的binLog维护两地缓存的一致性。
可以在需要时切换机房来保证服务的提供,而不会导致大量的冷数据回源数据库。
2、数据同步容灾
点赞job对binLog的容灾设计
由于点赞的存储为TiDB,且数据量较大。
在实际生产情况中,binLog会偶遇数据延迟甚至是断流的问题。
为了减少binLog数据延迟对服务数据的影响。
服务做了以下改造。
- 监控:
首先在运维层面、代码层面都对binLog的实时性、是否断流做了监控
- 应对
脱离binlog,由业务层(thumb-service)发送重要的数据信息(点赞数变更、点赞状态事件)等。
当发生数据延迟时,程序会自动同时消费由thumbup-service发送的容灾消息,继续向下游发送。
3、服务层的容灾与降级
(以点赞数、点赞状态、点赞列表为例),点赞作为一个用户强交互的社区功能服务,对于灾难发生时用户体验的保证是放在第一位的。
所以针对重点接口,B站都会有兜底的数据作为返回。
多层数据存储互为灾备
- 点赞的热数据在redis缓存中存有一份。
- kv数据库中存有全量的用户数据,当缓存不可用时,KV数据库会扛起用户的所有流量来提供服务。
- TIDB目前也存储有全量的用户数据,当缓存、KV均不可用时,tidb会依托于限流,最大程度提供用户数据的读写服务。
- 因为存在多重存储,所以一致性也是业务需要衡量的点。
- 首先写入到每一个存储都是有错误重试机制的,且重要的环节,比如点赞记录等是无限重试的。
- 另外,在拥有重试机制的场景下,极少数的不同存储的数据不一致在点赞的业务场景下是可以被接受的
多地方机房互为灾备
- 点赞机房、缓存、数据库等都在不同机房有备份数据,可以在某一机房或者某地中间件发生故障时快速切换。
点赞重点接口的降级
- 点赞数、点赞、列表查询、点赞状态查询等接口,在所有兜底、降级能力都已失效的前提下也不会直接返回错误给用户,而是会以空值或者假特效的方式与用户交互。
- 后续等服务恢复时,再将故障期间的数据写回存储。
架构的演进方向
架构方案,没有最优,只有更优。
B站的点赞中台后续的演进方向大致为:
- 点赞服务单元化:要陆续往服务单元化的方向迭代、演进。
- 点赞服务平台化:在目前的业务接入基础上增加迭代数据分库存储能力,做到服务、数据自定义隔离。
所以,以上才是“教科书式” 答案:
结合 B站的方案,大家回到前面的面试题:
- 千万级数据,如何做系统架构?
- 亿级数据,如何做做系统架构?
- 千万级流量,如何做系统架构?
- 亿级流量,如何做做系统架构?
- 高并发系统,如何架构?
以上的方案,才是完美的答案,才是“教科书式” 答案。后续尼恩会给大家结合行业案例,分析出更多,更加劲爆的答案。当然,如果遇到这类问题,还可以找尼恩求助。
推荐阅读:
《吃透8图1模板,人人可以做架构》
《干翻 nio ,王炸 io_uring 来了 !!(图解+史上最全)》
《SpringCloud+Dubbo3 = 王炸 !》
《响应式圣经:10W字,实现Spring响应式编程自由》
《4次迭代,让我的 Client 优化 100倍!泄漏一个 人人可用的极品方案!》
《100亿级订单怎么调度,来一个大厂的极品方案》
《Linux命令大全:2W多字,一次实现Linux自由》
《阿里一面:你做过哪些代码优化?来一个人人可以用的极品案例》
《网易二面:CPU狂飙900%,该怎么处理?》
《阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了》
《峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?》
《场景题:假设10W人突访,你的系统如何做到不 雪崩?》
《2个大厂 100亿级 超大流量 红包 架构方案》
《Nginx面试题(史上最全 + 持续更新)》
《K8S面试题(史上最全 + 持续更新)》
《操作系统面试题(史上最全、持续更新)》
《Docker面试题(史上最全 + 持续更新)》
《Springcloud gateway 底层原理、核心实战 (史上最全)》
《Flux、Mono、Reactor 实战(史上最全)》
《sentinel (史上最全)》
《Nacos (史上最全)》
《TCP协议详解 (史上最全)》
《分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)》
《clickhouse 超底层原理 + 高可用实操 (史上最全)》
《nacos高可用(图解+秒懂+史上最全)》
《队列之王: Disruptor 原理、架构、源码 一文穿透》
《环形队列、 条带环形队列 Striped-RingBuffer (史上最全)》
《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)》
《单例模式(史上最全)》
《红黑树( 图解 + 秒懂 + 史上最全)》
《分布式事务 (秒懂)》
《缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)》
《缓存之王:Caffeine 的使用(史上最全)》
《Java Agent 探针、字节码增强 ByteBuddy(史上最全)》
《Docker原理(图解+秒懂+史上最全)》
《Redis分布式锁(图解 - 秒懂 - 史上最全)》
《Zookeeper 分布式锁 - 图解 - 秒懂》
《Zookeeper Curator 事件监听 - 10分钟看懂》
《Netty 粘包 拆包 | 史上最全解读》
《Netty 100万级高并发服务器配置》
《Springcloud 高并发 配置 (一文全懂)》
相关文章:
1000亿数据、30W级qps如何架构?来一个天花板案例
1000亿级存储、30W级qps系统如何架构?来一个天花板案例 说在前面 在尼恩的(50)读者社群中,经常遇到一个 非常、非常高频的一个架构面试题,类似如下: 千万级数据,如何做系统架构?亿…...
人工智能及其应用(蔡自兴)期末复习
人工智能及其应用(蔡自兴)期末复习 相关资料: 人工智能期末复习 人工智能复习题 人工智能模拟卷 人工智能期末练习题 1 ⭐️绪论 人工智能:人工智能就是用人工的方法在机器(计算机)上实现的智能࿰…...
openpnp - configure - 矫正里程碑
文章目录openpnp - configure - 矫正里程碑概述备注ENDopenpnp - configure - 矫正里程碑 概述 进入矫正里程碑了 查找问题 现在第一个问题是X轴的齿隙矫正 根据提示, 将顶部相机移动到主基准点上, 选择容差(就选用默认的0.025), 开始矫正. 正好开机后, 使能了视觉原点归零. …...
JavaScript高级程序设计读书分享之8章——8.2创建对象
JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 创建Object的实例 let person new Object(); person.name "Nicholas"; person.age 29; person.job "Software Engineer"; person.sayName function() { console.log(this…...
关于Could not build wheels for opencv-python-headless, which is...报错的解决方案
在通过最新版pip在线安装package:opencv-python-headless的时候,会产生报错信息,主要为 ERROR: Failed building wheel for opencv-python-headless ERROR: Could not build wheels for opencv-python-headless, which is required to insta…...
【K3s】第1篇 K3s入门级介绍及架构详解
1、什么是 K3s? K3s 是一个轻量级的 Kubernetes 发行版,它针对边缘计算、物联网等场景进行了高度优化。K3s 有以下增强功能: 打包为单个二进制文件。使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、MySQL 和 PostgreSQL 作…...
Java学习--反射
1. 反射 1.1 反射的概述: **专业的解释(了解一下):**是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意属性和方法ÿ…...
应用和迭代(名词解释)
应用和迭代是什么意思 应用: ● 一个完整的前端应用,一般用应用脚手架创建,包含路由,页面,状态等 ● 一个应用对应一个代码仓库 ● 应用的分组(业务中心,数据中台等)只用于逻辑分类&…...
HTMLCollection 和 NodeList 区别
Node 和 Element DOM 是一棵树,所有节点都是 NodeNode 是 Element 的基类Element 是其他 HTML 元素的基类,如 HTMLDivElement HTMLCollection 和 NodeList HTMLCollection 是 Element 的集合NodeList 是 Node 的集合 <body><p id"p1&qu…...
fork()出来一个进程,这个进程的父进程是从哪来的?
基本概念fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process.fork()是一个系统调用,不是一个函数。详细信息可以,man…...
结构体内存对齐
结构体相信大家已经了解过了,现在我们深入讨论一个问题,计算结构体的大小 也是很热门的一个考点:结构体内存对齐 先看看下面结构体的大小 typedef struct Test {char a;char b;char c; }Test; 很容易看出答案为3,结构体的大小位…...
【C语言进阶】指针进阶
今日所做之事勿候明天,自我所做之事勿候他人。 --歌德 目录 指针进阶(更深层次的理解): 一.字符指针 二.指针数组 三.数组指针 1.数组指针的定义: 2.&数组名和数组名: 3.数组指针的使用: 四.数组参数,指针参数 1.一维数组传参:…...
java:Class的isPrimitive方法使用
java:Class的isPrimitive方法使用 1 前言 java中Class类的isPrimitive方法,用于检查类型是否为基本类型。java虚拟机创建了int、byte、short、long、float、double、boolean、char这8种基础信息,以及void,一共9种。为这9种类型时…...
TCP 握手过程 三次 四次
蛋老师视频 SYN 同步 ACK 确认 FIN 结束 核心机制是确定哪些请求或响应需要丢弃 SYN、ACK、FIN 通过 1/0 设置开启/关闭 开启SYN后,报文中会随机生成 Sequence序号 用于校验 (应用可能发起多个会话,可以区分) 服务器的同步序…...
windows 下 安裝mysql 5.7.41 (64位) 超简单方式
文章目录1. 安装包下载2.安装步骤3. 服务卸载方式4. 配上 my.ini 常用配置1. 安装包下载 注意,截至2023年2月23日,MySQL所有版本不提供ARM芯片架构的Windows版本(8.0.12开始支持Red Hat系统的ARM版本),所以ARM架构的Windows无法安装MySQL&am…...
二叉树——二叉树的最近公共祖先
二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一…...
数据结构与算法基础-学习-14-线性表之串
一、串的定义由0-n个字符组成的有限序列。(n>0)二、串的相关术语1、子串串中任意个连续字符组成的子序列成为该串的子串。2、主串包含子串的串成为主串。3、字符位置字符在序列中的序号为该字符在串中的位置。4、子串位置子串第一个字符在主串中的位置…...
Mac 快捷键
目录 命令行快捷键 命令行快捷键 control d 命令行中代表发送EOF终止输入 control u 删除光标之前到行首的字符 control k 删除光标之前到行尾的字符(比较常用) control a 移动光标到行首(常用) control e 移动光标到行尾 control l 清屏,相当于clear命令 con…...
【微服务】-微服务环境搭建
目录 2.1 技术选型 2.2 模块设计 2.3 微服务调用 2.4 创建⽗⼯程 2.5 创建商品微服务 2.6 创建订单微服务 2.1 技术选型 持久层: SpingData Jpa 数据库: MySQL5.7 其他: SpringCloud Alibaba 技术栈 2.2 模块设计 --- shop-parent ⽗⼯程 --- shop-product-api 商品微服…...
IGKBoard(imx6ull)-ADC编程MQ-2烟雾传感器采样
文章目录1- ADC介绍2- MQ-2烟雾传感器介绍(1)工作原理(2)MQ-2应用电路3- MQ-2烟雾传感器硬件连接4- ADC驱动配置5- 编程查看当前浓度1- ADC介绍 ADC是Analog-to-Digital Converter的缩写,指模数转换器。真实世界的模拟…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
