HDFS体系结构
HDFS 支持主从结 构 , 主节 点 称为 NameNode ,从节点称为 DataNode
HDFS中还包含一个 SecondaryNameNode 进程,只要辅助主节点
公司BOSS:NameNode (NN)
秘书:SecondaryNameNode (2NN)
员工:DataNode
NameNode介绍
首先是NameNode,NameNode是整个文件系统的管理节点,它主要维护着整个文件系统的文件目录树,文件/目录的信息 和 每个文件对应的数据块列表,并且还负责接收用户的操作请求。
文件/目录的信息:表示文件/目录的的一些基本信息,所有者 属组 修改时间 文件大小等信息。
每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储的时候会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储到不同机器上面。所以HDFS还要记录一下一个文件到底被分了多少块,每一块都在什么地方存储着接收用户的操作请求:其实我们在命令行使用hdfs操作的时候,是需要先和namenode通信 才能开始去操作数据的。
这些元数据存在哪里,hdfs-default.xml的dfs.namenode.name.dir属性决定,hdfs-site.xml文件属于hdfs-default.xml的一个扩展,它可以覆盖掉hdfs-default.xml中同名的参数。
[root@bigdata01 name]# cd /data/hadoop_repo/dfs/name
[root@bigdata01 name]# lltotal 8
drwxr-xr-x. 2 root root 4096 Apr 8 21:31 current
-rw-r--r--. 1 root root 14 Apr 8 20:30 in_use.lock
[root@bigdata01 name]# cd current
[root@bigdata01 current]# ll
total 4152
-rw-r--r--. 1 root root 42 Apr 7 22:17 edits_0000000000000000001-000000-rw-r--r--. 1 root root 1048576 Apr 7 22:17 edits_0000000000000000003-000000
-rw-r--r--. 1 root root 42 Apr 7 22:22 edits_0000000000000000004-000000
-rw-r--r--. 1 root root 1048576 Apr 7 22:22 edits_0000000000000000006-000000
-rw-r--r--. 1 root root 42 Apr 8 14:53 edits_0000000000000000007-000000
-rw-r--r--. 1 root root 1644 Apr 8 15:53 edits_0000000000000000009-000000
-rw-r--r--. 1 root root 1523 Apr 8 16:53 edits_0000000000000000032-000000
-rw-r--r--. 1 root root 42 Apr 8 17:53 edits_0000000000000000052-000000
-rw-r--r--. 1 root root 1048576 Apr 8 17:53 edits_0000000000000000054-000000
-rw-r--r--. 1 root root 42 Apr 8 20:31 edits_0000000000000000055-000000
-rw-r--r--. 1 root root 523 Apr 8 21:31 edits_0000000000000000057-000000
-rw-r--r--. 1 root root 1048576 Apr 8 21:31 edits_inprogress_000000000000000
-rw-r--r--. 1 root root 652 Apr 8 20:31 fsimage_0000000000000000056
-rw-r--r--. 1 root root 62 Apr 8 20:31 fsimage_0000000000000000056.md5
-rw-r--r--. 1 root root 661 Apr 8 21:31 fsimage_0000000000000000065
-rw-r--r--. 1 root root 62 Apr 8 21:31 fsimage_0000000000000000065.md5
-rw-r--r--. 1 root root 3 Apr 8 21:31 seen_txid
-rw-r--r--. 1 root root 219 Apr 8 20:30 VERSION
-
fsimage
是 HDFS 文件系统的元数据快照,记录了当前文件系统的完整状态,包括:-
文件和目录的层次结构。
-
文件和目录的权限、所有者、组等信息。
-
文件块(Block)的映射信息。
-
-
fsimage
文件通常与edits
文件一起使用,edits
文件记录了自上次fsimage
生成以来的所有更改。 -
fsimage文件有两个文件名相同的,有一个后缀是md5,md5是一种加密算法,这个其实主要是为了做md5校验的,为了保证文件传输的过程中不出问题,根据md5对fsimage的内容进行加密,获取一个值 和fsimage.md5中的内容进行比较,如果一样,说明接收到的文件就是完整的。
查看fsimage
文件
[root@bigdata01 current]# hdfs oiv -p XML -i fsimage_0000000000000000056
hdfs oiv
:
oiv
是 Offline Image Viewer 的缩写,是 HDFS 提供的一个工具,用于离线查看和分析fsimage
文件。
fsimage
是 HDFS 文件系统的元数据快照,包含了文件、目录、权限等信息。
-p XML
:
-p
指定输出格式。
XML
是其中一种输出格式,表示将fsimage
文件转换为 XML 格式。
-i fsimage_0000000000000000056
:
-i
指定输入的fsimage
文件。
fsimage_0000000000000000056
是具体的fsimage
文件名。会获得到一个xml 文件 xml 里面有个 标签<inode>,这个inode表示是hdfs中的每一个目录或者文件信息
id:唯一编号
type:文件类型replication:文件的副本数量
mtime:修改时间atime:访问时间
preferredBlockSize:推荐每一个数据块的大小
permission:权限信息
blocks:包含多少数据块【文件被切成数据块】
block:内部的id表示是块id,genstamp是一个唯一编号,numBytes表示当前数据块的实际大小,storagePolicyId表示是数据的存储策略
查看 edits 文件
[root@bigdata01 current]# hdfs oev -i edits_0000000000000000057-000000000000
<RECORD><OPCODE>OP_ADD</OPCODE><DATA><TXID>58</TXID><LENGTH>0</LENGTH><INODEID>16396</INODEID><PATH>/user.txt</PATH><REPLICATION>3</REPLICATION><ATIME>1586349095694</ATIME><BLOCKSIZE>134217728</BLOCKSIZE><CLIENT_NAME>DFSClient_NONMAPREDUCE_-1768454371_1</CLIENT_NAME><CLIENT_MACHINE>192.168.182.1</CLIENT_MACHINE><OVERWRITE>true</OVERWRITE><PERMISSION_STATUS><USERNAME>yehua</USERNAME><GROUPNAME>supergroup</GROUPNAME><MODE>420</MODE></PERMISSION_STATUS><ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID><RPC_CLIENTID>1722b83a-2dc7-4c46-baa9-9fa956b755cd</RPC_CLIENTID><RPC_CALLID>0</RPC_CALLID></DATA></RECORD><RECORD><OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE><DATA><TXID>59</TXID><BLOCK_ID>1073741830</BLOCK_ID></DATA></RECORD><RECORD><OPCODE>OP_SET_GENSTAMP_V2</OPCODE><DATA><TXID>60</TXID><GENSTAMPV2>1006</GENSTAMPV2></DATA></RECORD><RECORD><OPCODE>OP_ADD_BLOCK</OPCODE><DATA><TXID>61</TXID><PATH>/user.txt</PATH><BLOCK><BLOCK_ID>1073741830</BLOCK_ID><NUM_BYTES>0</NUM_BYTES><GENSTAMP>1006</GENSTAMP></BLOCK><RPC_CLIENTID/><RPC_CALLID>-2</RPC_CALLID></DATA></RECORD><RECORD><OPCODE>OP_CLOSE</OPCODE><DATA><TXID>62</TXID><LENGTH>0</LENGTH><INODEID>0</INODEID><PATH>/user.txt</PATH><REPLICATION>3</REPLICATION> <MTIME>1586349096480</MTIME> <ATIME>1586349095694</ATIME> <BLOCKSIZE>134217728</BLOCKSIZE> <CLIENT_NAME/><CLIENT_MACHINE/><OVERWRITE>false</OVERWRITE><BLOCK><BLOCK_ID>1073741830</BLOCK_ID><NUM_BYTES>17</NUM_BYTES> <GENSTAMP>1006</GENSTAMP> </BLOCK><PERMISSION_STATUS><MODE>420</MODE></PERMISSION_STATUS></DATA></RECORD>
OP_ADD:执行上传操作
OP_ALLOCATE_BLOCK_ID:申请block块idOP_SET_GENSTAMP_V2:设置GENSTAMP
OP_ADD_BLOCK:添加block块
OP_CLOSE:关闭上传操作
edits文件会定期合并到fsimage文件中,其实edits中保存的内容太细了,单单一个上传操作就分为了好几步,其实上传成功之后,我们只需要保存文件具体存储的block信息就行,所以在合并的时候其实是对edits中的内容进行了精简。 2NN负责定期的把edits中的内容合并到fsimage中。在 NameNode 的 HA 架 构 中 没 有 SecondaryNameNode 进 程 , 文 件 合 并 操 作 会 由 standby
NameNode负责实现,所以在Hadoop集群中,SecondaryNameNode进程并不是必须的。
current目录中还有一个seen_txid文件,HDFS 格式化之后是0,它代表的是namenode里面的edits_*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。
DataNode介绍
DataNode是提供真实文件数据的存储服务,针对datanode主要掌握两个概念,一个是block(默认128MB),一个是replication。
datanode中数据的具体存储位置是由dfs.datanode.data.dir来控制的,通过查询hdfs-default.xml可以知道。
namenode维护了两份关系
第一份关系:file 与block list的关系,对应的关系信息存储在fsimage和edits文件中,当NameNode启动的时候会把文件中的元数据信息加载到内存中刚才我们说了NameNode启动的时候会把文件中的元数据信息加载到内存中,然后每一个文件的元数据信息会占用150字节的内存空间,这个是恒定的,和文件大小没有关系,咱们前面在介绍HDFS的时候说过,HDFS不适合存储小文件,其实主要原因就在这里,不管是大文件还是小文件,一个文件的元数据信息在NameNode中都会占用150字节,NameNode节点的内存是有限的,所以它的存储能力也是有限的,如果我们存储了一堆都是几KB的小文件,最后发现NameNode的内存占满了
第二份关系:datanode与block的关系,对应的关系主要在集群启动的时候保存在内存中,当DataNode启动时会把当前节点上的Block信息和节点信息上报给NameNode
namenode不要随便格式化,因为格式化了以后VERSION里面的clusterID会变,但是datanode的VERSION中的clusterID并没有变,所以就对应不上了。
[root@bigdata01 current]# cat VERSION
#Wed Apr 08 20:30:00 CST 2020namespaceID=498554338clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=1586268855170
storageType=NAME_NODEblockpoolID=BP-1517789416-192.168.182.100-1586268855170layoutVersion=-65如果确实要重新格式化的话需要把/data/hadoop_repo数据目录下的内容都清空,全部都重新生成是可以的。
HDFS的回收站
HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/,每一个被用户在Shell命令行删除的文件/目录,会进入到对应的回收站目录中,在回收站中的数据都有一个生存周期,也就是当回收站中的文件/目录在一段时间之内没有被用户恢复的话,HDFS就会自动的把这个文件/目录彻底删除,之后,用户就永远也找不回这个文件/目录了。
core-site.xml
<property><name>fs.trash.interval</name><value>1440</value>
</property>
指定参数 -skipTrash ,指定这个参数表示删除的文件不会进回收站
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r -skipTrash /user.txt
Deleted /user.txt
HDFS的安全模式
[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode get
Safe mode is ON
// on表示处于安全模式,off表示安全模式已结束
// 通过命令强制离开
[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode leave
Safe mode is OFF
nameNode负责接收用户的操作请求,所有的读写请求都会经过它,如果它挂了怎么办?
集群就太不稳定了,因为NameNode只有一个,是存在单点故障的,咱们在现实生活中,例如,县长,是有正的和副的,这样就是为了解决当正县长遇到出差的时候,副县长可以顶上去。
所以在HDFS的设计中,NameNode也是可以支持多个的,一个主的 多个备用的,当主的挂掉了,备用的可以顶上去,这样就可以解决NameNode节点宕机导致的单点故障问题了,也就实现了HDFS的高可用。
HDFS的高可用(HA)
HDFS的HA,指的是在一个集群中存在多个NameNode,分别运行在独立的物理节点上。在任何时间点,只有一个NameNode是处于Active状态,其它的是处于Standby状态。 Active NameNode(简写为Active NN)负责所有的客户端的操作,而Standby NameNode(简写为Standby NN)用来同步ActiveNameNode的状态信息,以提供快速的故障恢复能力。
为了保证Active NN与Standby NN节点状态同步,即元数据保持一致。除了DataNode需要向这些NameNode发送block位置信息外,还构建了一组独立的守护进程”JournalNodes”(简写为JN),用来同步Edits信息。当Active NN执行任何有关命名空间的修改,它需要持久化到一半以上的JNs上。而Standby NN负责观察JNs的变化,读取从Active NN发送过来的Edits信息,并更新自己内部的命名空间。一旦Active NN遇到错误,Standby NN需要保证从JNs中读出了全部的Edits,然后切换成Active状态,如果有多个Standby NN,还会涉及到选主的操作,选择一个切换为Active 状态。
元数据保持一致,包含两块,一个是静态的,一个是动态的
静态的是fsimage和edits,其实fsimage是由edits文件合并生成的,所以只需要保证edits文件内容的一致性。这个就是需要保证多个NameNode中edits文件内容的事务性同步。这块的工作是由JournalNodes集群进行同步的
动态数据是指block和DataNode节点的信息,这个如何保证呢?当DataNode启动的时候,上报数据信息的时候需要向每个NameNode都上报一份。这样就可以保证多个NameNode的元数据信息都一样了,当一个NameNode down掉以后,立刻从Standby NN中选择一个进行接管,没有影响,因为每个NameNode 的元数据时刻都是同步的。
使用zookeeper集群自动切换NameNode的原理
当多个NameNode 启动的时候会向zookeeper中注册一个临时节点,当NameNode挂掉的时候,这个临时节点也就消失了,这属于zookeeper的特性,这个时候,zookeeper就会有一个watcher监视器监视到,就知道这个节点down掉了,然后会选择一个节点转为Active,把down掉的节点转为Standby。
namenode:hdfs的主节点datanode:hdfs的从节点
journalnode:JournalNode进程,用来同步Edits信息的
zkfc(DFSZKFailoverController):监视namenode的状态,负责切换namenode节点的状态
zookeeper(QuorumPeerMain):保存ha集群的节点状态信息
相关文章:

HDFS体系结构
HDFS 支持主从结 构 , 主节 点 称为 NameNode ,从节点称为 DataNode HDFS中还包含一个 SecondaryNameNode 进程,只要辅助主节点 公司BOSS:NameNode (NN) 秘书:SecondaryNameNode (2NN) 员工&a…...
AI大模型的技术突破与传媒行业变革
性能与成本:AI大模型的“双轮驱动” 过去几年,AI大模型的发展经历了从实验室到产业化的关键转折。2025年初,以DeepSeek R1为代表的模型在数学推理、代码生成等任务中表现超越国际头部产品,而训练成本仅为传统模型的几十分之一。这…...

vscode/cursor+godot C#中使用socketIO
在 Visual Studio Code(VS Code)中安装 NuGet 包(例如SocketIOClient),你可以通过以下几种方法: 方法 1:使用dotnet cli 打开终端:在 VS Code 中按下Ctrl 或者通过菜单View -> Terminal打开终端。 导…...
分段线性插值
分段线性插值 分段线性插值,就是将插值点用折线段连接起来逼近f(x)。设已知节点 a x 0 < x 1 < ⋅ ⋅ ⋅ < x n b ax_0<x_1<<x_nb ax0<x1<⋅⋅⋅<xnb上的函数值 f 0 , f 1 , . . . , f n f_0,f_1,...,f_n f0,f1,...,fn&a…...

制作一个项目用于研究elementUI的源码
需求:修改el-tooltip的颜色,发现传递参数等方法都不太好用,也可以使用打断点的方式,但也有点麻烦,因此打算直接修改源码,把组件逻辑给修改了 第一步下载源码 源码地址 GitHub - ElemeFE/element: A Vue.j…...

[AI]从零开始的llama.cpp部署与DeepSeek格式转换、量化、运行教程
一、前言 在上一次的DeepSeek的部署教程中,我们使用Ollama与LM Studio很轻松的部署了DeepSeek并且也完成了相关API的调用,如果还有不会的小伙伴请看下面的教程: DeepSeek本地部署:[AI]从零开始的DeepSeek本地部署及本地API调用教…...
vLLM专题(二):安装-CPU
vLLM 是一个 Python 库,支持以下 CPU 变体。选择您的 CPU 类型以查看供应商特定的说明: Intel/AMD x86 vLLM 最初支持在 x86 CPU 平台上进行基本模型推理和服务,支持的数据类型包括 FP32、FP16 和 BF16。 注意 此设备没有预构建的 wheel 包或镜像,因此您必须从源代码构建 v…...

JVM 底层探秘:对象创建的详细流程、内存分配机制解析以及线程安全保障策略
文章目录 1. 类加载检查2. 内存分配① 指针碰撞② 空闲列表线程安全问题: 3. 内存空间初始化4. 对象头设置5. 对象初始化 当Java虚拟机遇到一条 new指令时,会执行以下步骤来创建对象: 1. 类加载检查 首先检查new指令的参数是否能在常量池中…...
【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter14-DOM
十四、DOM 文档对象模型(DOM,Document Object Model)是 HTML 和 XML 文档的编程接口。DOM 表示由多层节点构成的文档,通过它开发者可以添加、删除和修改页面的各个部分。脱胎于网景和微软早期的动态 HTML(DHTML&#x…...
外汇掉期(FX Swap):全球企业管理外汇风险的关键工具(中英双语)
外汇掉期(FX Swap):全球企业管理外汇风险的关键工具 引言 在全球化经济环境下,跨国公司、银行和金融机构经常面临外汇风险,因为它们的业务涉及多种货币。例如,一家中国公司可能需要欧元支付欧洲供应商&am…...
verilog程序设计及SystemVerilog验证
1.Verilog测试程序设计基础 1.1Testbench及其结构 在仿真的时候Testbench用来产生测试激励给待验证设计( Design Under Verification, DUV),或者称为待测设计(Design UnderTest, DUT) 。 测试程序的一般结构: Testbench是一个测试平台,信号…...

Unity DeepSeek API 聊天接入教程(0基础教学)
Unity DeepSeek API 聊天接入教程(0基础教学) 1.DeepSeek 介绍 DeepSeek是杭州深度求索人工智能基础技术研究有限公司推出的一款大语言模型。2025年1月20日,DeepSeek-R1正式上线,和当前市面上的主流AI相比,它在仅有极少标注数据的情况下&am…...

力扣 乘积最大子数组
动态规划,注意负负得正,dp交换。 题目 注意这里的dp的乘积要求最大,而两个很大的负数相乘也是大的,因此在每遍历到一个数时要存一个最大值的dp与一个最小值的dp,然后遍历完后再去存ans的dp。由于存在负数,…...

ABP - 事件总线之分布式事件总线
ABP - 事件总线之分布式事件总线 1. 分布式事件总线的集成1.2 基于 RabbitMQ 的分布式事件总线 2. 分布式事件总线的使用2.1 发布2.2 订阅2.3 事务和异常处理 3. 自己扩展的分布式事件总线实现 事件总线可以实现代码逻辑的解耦,使代码模块之间功能职责更清晰。而分布…...
osgearth控件显示中文(八)
当前自己知道的方法大概有以下两种: (一)直接转成utf8 其实在前面的文章中已经有了。 osgEarth::Annotation::PlaceNode *pn = new osgEarth::Annotation::PlaceNode(GeoPoint(geoSRS, 110, 34), String2UTF8("中国"), style);std::wstring String2Wstring(con…...

基于opencv的 24色卡IQA评测算法源码-可完全替代Imatest
1.概要 利用24色卡可以很快的分析到曝光误差,白平衡误差,噪声,色差,饱和度,gamma值。IQA或tuning工程一般用Imatest来手动计算,不便于产测部署,现利用opencv实现了imatest的全部功能,…...
webpack打包优化策略
1. 减少打包体积 减少打包文件的大小是为了提高加载速度,降低网络带宽消耗,提升用户体验。常见的减少打包体积的优化策略包括: 代码分割(Code Splitting):将代码拆分成多个小文件,让浏览器按需…...
Kafka日志数据深度解析:从基础查看到高级操作全攻略
#作者:孙德新 文章目录 查看log日志文件(kafka-dump-log.sh)1、查看Log文件基本数据信息2、index文件健康性检查(--index-sanity-check)3、转储文件(--max-message-size)4、偏移量解码(--offsets-decoder)5、日志数据解析(--transaction-log-decoder)6、查询Log文件…...

DeepSeek-R1使用生存指南
文章目录 1.为什么普通人一定要使用DeepSeek2.DeepSeek的几种使用方式2.1网页端直接使用2.2手机端app使用2.3其他第三方平台 3.网页端按钮的说明4.正确的提问技巧4.1不要定义过程4.2明确受众4.3记忆时间有限4.4输出长度限制4.5如何清除上下文的记忆 5.几个避坑点5.1冗长提示词污…...

Code::Blocks 创建 C 项目 二
Code::Blocks 创建 C 项目 二 Code::Blocks 安装请看 Code::Blocks 安装 启动 Code Blocks 选择 Create a new project 弹出界面选择 Projects -> Console application -> Go 选择 C :表示创建的是 C 语言项目 点击 Next Project title:项目名 …...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...