Kubernetes控制平面组件:API Server代码基础概念
云原生学习路线导航页(持续更新中)
- kubernetes学习系列快捷链接
- Kubernetes架构原则和对象设计(一)
- Kubernetes架构原则和对象设计(二)
- Kubernetes架构原则和对象设计(三)
- Kubernetes控制平面组件:etcd(一)
- Kubernetes控制平面组件:etcd(二)
- Kubernetes控制平面组件:API Server详解(一)
- Kubernetes控制平面组件:API Server详解(二)
本文主要对kubernetes的控制面组件API Server的代码阅读做一些前置准备,包括apimachinery项目的定位和核心包的介绍,API Server代码的一些基础操作,subresource概念、apiserver代码走读的关键点等
- 希望大家多多 点赞 关注 评论 收藏,作者会更有动力继续编写技术文章
1.apimachinery项目定位
- girhub:
- https://github.com/kubernetes/apimachinery
- https://github.com/kubernetes/kubernetes/tree/master/staging/src/k8s.io/apimachinery
- apimachinery 是 Kubernetes 生态中的底层基础设施库,为 Kubernetes API 的构建、操作和扩展提供基础能力。其核心定位体现在以下方面:
- 统一 API 基础设施:定义 Kubernetes API 的核心数据结构(如
TypeMeta
、ObjectMeta
)、类型系统(GVK/GVR 模型)和序列化机制(JSON/Protobuf),是客户端和服务端共享的依赖库 - 解耦核心组件:通过抽象 API 操作的通用逻辑(如版本转换、资源发现),使 Kubernetes 主仓库(k8s.io/kubernetes)、客户端库(client-go)和扩展组件(如 CRD 控制器)无需直接依赖核心代码
- 支撑扩展生态:提供自定义资源(CRD)和聚合层(Aggregated APIServer)的基础能力,是构建 Operator、Service Mesh 等云原生组件的基石
- 统一 API 基础设施:定义 Kubernetes API 的核心数据结构(如
2.apimachinery的核心能力与基本原理
2.1.核心能力
- 类型系统管理
- 定义 Kubernetes 资源的元数据(
TypeMeta
、ObjectMeta
)和通用接口(如runtime.Object
),支持资源的版本化描述。
- 定义 Kubernetes 资源的元数据(
- 序列化与反序列化
- 提供 JSON/Protobuf 编码解码能力,通过
runtime.Scheme
实现类型与数据格式的动态映射。
- 提供 JSON/Protobuf 编码解码能力,通过
- 版本转换与兼容性
- 支持多版本 API 共存(如
v1
与v1beta1
),通过Convert
接口实现不同版本资源的自动转换。
- 支持多版本 API 共存(如
- 资源发现与操作
- 提供
RESTMapper
实现 GVK 到 GVR 的映射,支持动态客户端(dynamic.Client
)操作未预定义类型的资源。
- 提供
- 通用工具链
- 包含深拷贝(
DeepCopy
)、标签选择器(labels.Selector
)、字段选择器(fields.Selector
)等高频工具
- 包含深拷贝(
2.2.基本原理
-
Scheme 机制
runtime.Scheme
是核心组件,负责注册 Golang 类型与 GVK 的映射关系,并管理版本转换函数。例如:scheme := runtime.NewScheme() corev1.AddToScheme(scheme) // 注册核心类型
- 通过 Scheme,客户端可自动反序列化 API Server 返回的 JSON 数据为对应结构体。
-
GVK/GVR 模型
- GVK (Group/Version/Kind):标识资源的逻辑类型(如
apps/v1.Deployment
)。 - GVR (Group/Version/Resource):对应 API 路径(如
/apis/apps/v1/deployments
)。 - apimachinery 提供
meta.RESTMapper
实现两者的动态映射,支撑kubectl get deployments
等操作。
- GVK (Group/Version/Kind):标识资源的逻辑类型(如
-
类型注册与转换
- 资源类型需实现
runtime.Object
接口,并通过AddKnownTypes
注册到 Scheme。 - 版本转换通过
Convert
函数链实现,例如将v1beta1.Deployment
转换为v1.Deployment
。
- 资源类型需实现
2.3.apimachinery核心代码包
-
apimachinery 的代码结构围绕 类型系统 和 API 操作 展开,核心包如下:
包路径 功能描述 k8s.io/apimachinery/pkg/apis/meta
定义元数据( TypeMeta
、ObjectMeta
)和公共接口(如ListOptions
、DeleteOptions
)k8s.io/apimachinery/pkg/runtime
实现序列化( Serializer
)、Scheme 管理、类型转换等核心逻辑k8s.io/apimachinery/pkg/api/resource
处理资源配额(如 CPU/内存的单位转换) k8s.io/apimachinery/pkg/util
提供通用工具(如 wait
重试机制、sets
集合操作)k8s.io/apimachinery/pkg/version
定义 Kubernetes 版本信息结构 -
关键数据结构示例:
// TypeMeta 定义资源的 API 版本和类型 type TypeMeta struct {APIVersion string `json:"apiVersion,omitempty"`Kind string `json:"kind,omitempty"` }// ObjectMeta 定义资源的元数据(名称、标签等) type ObjectMeta struct {Name string `json:"name,omitempty"`Namespace string `json:"namespace,omitempty"`Labels map[string]string `json:"labels,omitempty"`Annotations map[string]string `json:"annotations,omitempty"` }
3.API Server代码的一些基础操作
3.1.如何定义一个Group
- 分为三步:
- 定义一个GV:Group+Version
- 定义一个SchemeBuilder
- 将GV下具体的对象加入SchemeBuilder
3.2.如何定义一个对象
- 对象一般都是在types.go文件中
3.3.使用代码生成的Tags
3.3.1.code-generator项目
-
code-generator项目:https://github.com/kubernetes/code-generator
-
code-generator项目下包含很多代码生成的工具,包括生成 深拷贝代码、client代码、informer代码、lister代码、conversion代码等
-
代码生成器,是通过文件中的 特定tag 生效的,比如下面有一些常用的tag
标签 解释 // +k8s:deepcopy-gen=package
全局标签,为包内所有类型生成深拷贝方法。 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
生成实现 runtime.Object
接口的深拷贝方法,用于序列化与版本转换。// +genclient
生成客户端代码(CRUD 方法、Lister、Informer)。 // +genclient:nonNamespaced
标记资源为集群作用域(Cluster-scoped),生成不带命名空间参数的方法。 // +genclient:noVerbs
不生成默认客户端方法(需配合其他标签指定特定动词)。 // +genclient:onlyVerbs=create,delete
仅生成指定的客户端方法(如仅 Create
和Delete
)。// +genclient:skipVerbs=get,list,watch
跳过生成指定的客户端方法(如 Get
、List
、Watch
)。// +genclient:method=Create,verb=create,result=...
自定义客户端方法名称、HTTP 动词及返回类型(如返回 metav1.Status
)。 -
说明:
- 全局标签作用于整个包,局部标签作用于单个资源。
- 标签需严格遵循格式(如空格不可省略),否则会被代码生成器忽略。
3.3.2.代码生成使用示例
- 通过编写脚本文件,指定code-generator项目下各种工具的路径,然后使用命令生成具体的代码。如下图:
--input-dirs
:源代码目录-O
:生成的文件名称--bounding-dirs
:输出目录--go-header-file
:加什么样的header描述
3.4.如何操作etcd
- 每一个etcd的对象都会有一个storage.go,定义如何与etcd交互。比如上面就是定义了configmap的etcd操作。
- 其中strategy为具体的操作策略,比如创建、修改、删除,操作前可以进行一些校验,平时我们操作cm报的错误,就都是这个strategy报的错误了
- 比如这里CreateStrategy里的validate方法,就是对cm的校验,看apiserver代码的时候,可以看这里的处理
3.5.将 API Group 注册到API Server
- 通过install方法,将GVK的某个资源 Handler注册到apiserver中,在发生对应事件的时候才知道怎么处理
4.subresource概念
4.1.subresource是什么
- Kubernetes 中 Pod 的 subresource(子资源) 是 Pod 主资源的扩展操作接口,用于实现特定场景下的精细化操作或状态管理。
4.2.常见的subresource
Pod 的子资源主要通过 Kubernetes API 路径区分,常见的子资源如下:
4.2.1.pod的status
- 功能:用于获取或更新 Pod 的运行时状态(如容器状态、Pod 阶段等)。状态信息由 kubelet 维护,用户可通过 kubectl get pod -o yaml 查看状态字段。
- API 路径:
/api/v1/namespaces/{namespace}/pods/{name}/status
4.2.2.pod容器执行的exec
- 功能:在 Pod 的容器内执行命令(类似 docker exec)。常用于调试容器内进程或获取实时日志
- 使用示例:
kubectl exec -it <pod-name> -- /bin/sh
- API 路径:
/api/v1/namespaces/{namespace}/pods/{name}/exec
4.2.3.pod容器的log
- 功能:获取 Pod 中容器的日志输出。支持按时间范围、容器名称过滤日志。
- 使用示例:
kubectl logs <pod-name> -c <container-name> --since=5m
- API 路径:
/api/v1/namespaces/{namespace}/pods/{name}/log
4.2.4.pod的端口转发portforward
- 功能:将本地端口转发到 Pod 的容器端口,便于本地访问容器内服务(如调试数据库)。
- 使用示例:
kubectl port-forward <pod-name> 8080:80
- API 路径:
/api/v1/namespaces/{namespace}/pods/{name}/portforward
4.3.子资源的核心原理
4.3.1.API 路径设计
- Kubernetes 的 RESTful API 通过路径后缀标识子资源。例如,对 Pod 的
exec
操作对应路径/pods/{name}/exec
,而非直接操作 Pod 主资源。
4.3.2.独立的权限控制
- 子资源的操作需通过 RBAC 独立授权。例如,
exec
和portforward
需要pods/exec
和pods/portforward
权限:apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole rules: - apiGroups: [""]resources: ["pods/exec", "pods/portforward"]verbs: ["create"]
4.3.3.status状态分离
status
子资源的设计遵循 声明式Declarative API 原则,将用户定义的期望状态(spec
)与系统维护的实际状态(status
)分离,避免并发写入冲突。- 因为status写入太频繁了,如果status直接操作pod主资源,容易与spec的update操作发生写入冲突,所以将status分离出来是非常有必要的
- 如下图,status有独立的StatusStrategy,在更新status时,会把spec的内容恢复为和环境一致,防止status的修改影响到spec
5.API Server代码走读
- https://cncamp.notion.site/kube-apiserver-10d5695cbbb14387b60c6d622005583d
cmd/kube-apiserver/app/server.go:NewAPIServerCommand()-->
completedOptions, err := Complete(s)-->s.Etcd.WatchCacheSizes, err = serveroptions.WriteWatchCacheSizes(sizes)
Run(completedOptions, genericapiserver.SetupSignalHandler())-->CreateServerChain()-->CreateServerChain()-->CreateKubeAPIServerConfig-->buildGenericConfig(s.ServerRunOptions, proxyTransport)-->genericapiserver.NewConfig(legacyscheme.Codecs) // create codec factory for encoding/decodingcontrolplane.DefaultAPIResourceConfigSource() // group version: enabled/disabledstorageFactoryConfig.Complete(s.Etcd)completedStorageFactoryConfig.New()--> // register access path in etcd for all k8s objectsstorageFactory.AddCohabitatingResources(networking.Resource("networkpolicies"), extensions.Resource("networkpolicies"))s.Etcd.ApplyWithStorageFactoryTo(storageFactory, genericConfig)-->c.AddHealthChecks()c.RESTOptionsGetter = &StorageFactoryRestOptionsFactory{Options: *s, StorageFactory: factory}
// API Server启动过程中,认证、鉴权、准入逻辑都是如何加载的
// 认证s.Authentication.ApplyTo()--> // clientcert, serviceaccount, bootstrap token, authenticatorConfig.New()-->newWebhookTokenAuthenticator(config) // webhook
// 鉴权BuildAuthorizer(s, genericConfig.EgressSelector, versionedInformers)-->authorizationConfig.New()-->rbacAuthorizer := rbac.New()--> // if authorizer type is rbac
// 准入buildServiceResolver(s.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers)admissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver)-->admission.PluginInitializer{webhookPluginInitializer, kubePluginInitializer}net.SplitHostPort(s.Etcd.StorageConfig.Transport.ServerList[0])utilwait.PollImmediate(etcdRetryInterval, etcdRetryLimit*etcdRetryInterval, preflight.EtcdConnection{ServerList: s.Etcd.StorageConfig.Transport.ServerList}.CheckEtcdServers)capabilities.Initialize() // allow privillage?config := &controlplane.Config{}createAPIExtensionsConfig()createAPIExtensionsServer()-->apiextensionsConfig.Complete().New(delegateAPIServer)-->s.AddHealthChecks(delegateCheck)
// 注册通用handlerinstallAPI(s, c.Config) // register generic api handler e.g. index, profiling, metrics, flow controlCreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer)kubeAPIServerConfig.Complete().New(delegateAPIServer)m.InstallLegacyAPI(&c, c.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider)-->m.GenericAPIServer.AddPostStartHookOrDie(controllerName, bootstrapController.PostStartHook)-->controlplane.controller.Start()-->async.NewRunner(c.RunKubernetesNamespaces, c.RunKubernetesService, repairClusterIPs.RunUntil, repairNodePorts.RunUntil)m.GenericAPIServer.AddPreShutdownHookOrDie(controllerName, bootstrapController.PreShutdownHook)
// 所有的API Group都是如何Install的
// 注册core group API handler
// API Server的watch cache时如何构建的,newEtcdStorage-newCache的时候,newWatchCache建立了缓存,实现了watch etcdm.GenericAPIServer.InstallLegacyAPIGroup() // register handler for /apirestStorageProviders := []RESTStorageProvider{appsrest.StorageProvider{}}m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...)-->
// 初始化对应group中对象的watch cacherestStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)--> // trigger appsrest.StorageProviderp.v1Storage(apiResourceConfigSource, restOptionsGetter)-->daemonsetstore.NewREST(restOptionsGetter)-->store.CompleteWithOptions(options)-->opts, err := options.RESTOptions.GetRESTOptions(e.DefaultQualifiedResource)--> // etcd.goret.Decorator = genericregistry.StorageWithCacher()-->cacherstorage.NewCacherFromConfig(cacherConfig)-->watchCache := newWatchCache()-->
// 注册API handlerm.GenericAPIServer.InstallAPIGroups(apiGroupsInfo...)--> // register handler for /apiss.installAPIResources(APIGroupPrefix, apiGroupInfo, openAPIModels)-->apiGroupVersion.InstallREST(s.Handler.GoRestfulContainer)-->discovery.NewAPIVersionHandler(g.Serializer, g.GroupVersion, staticLister{apiResources})createAggregatorServer(aggregatorConfig, kubeAPIServer.GenericAPIServer, apiExtensionsServer.Informers)-->apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)server.PrepareRun()-->s.GenericAPIServer.PrepareRun()-->s.installHealthz()s.installLivez()s.installReadyz()prepared.Run(stopCh)-->s.runnable.Run(stopCh)--> // preparedGenericAPIServer.Run()s.NonBlockingRun(delayedStopCh)-->s.SecureServingInfo.Serve(s.Handler, s.ShutdownTimeout, internalStopCh)-->RunServer(secureServer, s.Listener, shutdownTimeout, stopCh)
6.注意事项
6.1.kubernetes集群版本升级 与对象兼容性
- 需要注意,对于一个对象的版本,kubernetes只承诺向下兼容3个版本
- 比如在1.0引入了一个v1alpha1的对象A版本,在kubernetes的后面3个版本发布时,都会做v1alpha1的对象A版本的兼容性处理,但是再后面的kubernetes版本就不保证了,
- 所以在做kubernetes版本升级的时候不要跨太多版本,而且也要对你的Operator Controller等做好调查,不要升级kubernetes集群后发现Operator操作的对象不支持了
- 社区建议升级kubernetes集群版本时不要跳过任何版本,要一个个升上去,但是实践下来很难能跟上kubernetes发布的版本,在一些集群比较多的厂商中,一般会2-3个版本升级一次。
- 但即便这样,升级时也要非常仔细的读changeLog,不能忽略任何一句话
- 之前就发生过版本升级后pod的hash计算方法变化的场景,可能会造成pod重建
相关文章:
Kubernetes控制平面组件:API Server代码基础概念
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
修改PointLIO项目
添加key_frame_info.msg消息 新建.msg文件,内容填写为: # Cloud Info Header header # cloud messages sensor_msgs/PointCloud2 key_frame_cloud_ori sensor_msgs/PointCloud2 key_frame_cloud_transed sensor_msgs/PointCloud2 key_frame_poses其中k…...
将 JSON 字符串转化为对象的详细笔记 (Java示例)
1. 主流 JSON 库的选择 在 Java 中,常用以下库进行 JSON 和对象之间的转换: Jackson:Spring 默认集成,性能优异,支持流式解析。FastJSON:阿里开发,速度快,但需注意版本安全性。Gso…...
基于Docker+k8s集群的web应用部署与监控
项目架构图 server ip master 192.168.140.130 node1 192.168.140.131 node2 192.168.140.132 ansible 192.168.140.166 jumpserver 192.168.100.133 firewall 192.168.1.86 nfs 192.168.140.157 harbor 192.168.140.159 Promethethus 192.168.140.130 Jen…...
Java(自用查看版)
目录 1.java的基本运行 2、基本格式 注释 标识名 关键字 常量 整型常量 浮点数: 字符常量: 字符串常量 布尔 null值 变量 整型变量: 浮点变量: 字符变量: 布尔变量: 类型转换 自动类型转换 强制类型转换 运算符 …...
头歌java课程实验(函数式接口及lambda表达式)
第1关:利用lambda表达式对Book数组按多个字段进行排序 任务描述 本关任务:利用Comparator接口完成对Book数组同时按多个字段进行排序。 编程要求 1、本任务共有三个文件,可查看各文件的内容 2、无需修改SortBy.java枚举文件及Book.java类文…...
Jsp技术入门指南【九】详细讲解JSTL
Jsp技术入门指南【九】详细讲解JSTL 前言一、什么是JSTL?(JavaServer Pages Standard Tag Library)二、使用JSTL前的准备三、核心标签库常用标签详解1. <c:out>:输出内容(替代<% %>)2. <c:i…...
【C语言】用铁路系统来类比流,管道,进程,线程,内存,输入输出等
用**铁路网络**来比喻计算机中的这些概念会非常形象。下面是一个完整的类比体系,帮助你直观理解它们之间的关系: --- ### **1. 核心角色对照表** | **计算机概念** | **铁路网络比喻** | |--------…...
PCA——主成分分析数学原理及代码
主成分分析 PCA的目的是:对数据进行一个线性变换,在最大程度保留原始信息的前提下去除数据中彼此相关的信息。反映在变量上就是说,对所有的变量进行一个线性变换,使得变换后得到的变量彼此之间不相关,并且是所有可能的…...
[Windows] Adobe Camera Raw 17.2 win/Mac版本
[Windows] Adobe Camera Raw 链接:https://pan.xunlei.com/s/VOOIAXoyaZcKAkf_NdP-qw_6A1?pwdpd5k# Adobe Camera Raw,支持Photoshop,lightroom等Adobe系列软件,对相片无损格式进行编辑调色。 支持PS LR 2022 2023 2024 2025版…...
基于计算机视觉的行为检测:从原理到工业实践
一、行为检测的定义与核心价值 行为检测(Action Recognition)是计算机视觉领域的关键任务,旨在通过分析视频序列理解人类动作的时空特征。其核心价值体现在时序建模和多尺度分析能力上——系统需要捕捉动作的起始、发展和结束全过程,同时适应不同持续时间(0.1秒至数分钟)…...
基于 OpenCV 的图像与视频处理
基于 OpenCV 的图像处理 一、实验背景 OpenCV 是一个开源的计算机视觉库,广泛应用于图像处理、视频分析、目标检测等领域。通过学习 OpenCV,可以快速实现图像和视频的处理功能,为复杂的应用开发 奠定基础。本实验旨在通过实际代码示例&…...
B树的异常恢复
B-Tree & Crash Recovery B树作为平衡的n叉树 高度平衡树 许多实用的二叉树(如AVL树或红黑树)被称为高度平衡树,这意味着树的高度(从根节点到叶子节点)被限制为Ο(log 𝑁),因此查找操作的…...
Centos9 离线安装 MYSQL8
centos 9 离线安装 mysql 8 参考教程 1. 官网下载mysql 下载地址 2. 将文件传输到Centos中解压 软件全部安装到了/opt中 在opt中新建mysql目录,解压到mysql目录中 tar -xvf mysql压缩文件 mysql[rootcentoshost mysql]# ls mysql-community-client-8.4.5-1.e…...
【RabbitMQ | 第2篇】RabbitMQ 控制台实现消息路由 + 数据隔离
文章目录 同步调用和异步调用MQRabbitMQ1. RabbitMQ控制台实现交换机路由到队列1.1 创建队列1.2 将消息发送给交换机,是否会到达队列 2. RabbitMQ控制台实现数据隔离2.1 添加一个用户2.2 创建新的虚拟主机 同步调用和异步调用 同步调用是指完成一个功能,…...
算法—选择排序—js(场景:简单实现,不关心稳定性)
选择排序原理:(简单但低效) 每次从未排序部分选择最小元素,放到已排序部分的末尾。 特点: 时间复杂度:O(n) 空间复杂度:O(1) 不稳定排序 // 选择排序 function selectionSort(arr) {for (let …...
龙舟中国行走进湖南娄底 2025湖南省龙舟联赛娄底站盛大举行
鼓声震天破碧波,百舸争流显豪情。2025年4月20日星期日,"龙舟中国行2025"首站——龙舟中国行走进湖南娄底2025湖南省龙舟联赛娄底双峰站在双峰县湄水河育才桥至风雨桥水域火热开赛。12支劲旅劈波斩浪,在青山绿水间上演传统与现代交织…...
重构之去除多余的if-else
一、提前返回(Guard Clauses) 适用场景:当 else 块仅用于处理异常或边界条件时。 优化前:if (isValid) {doSomething(); } else {return; }优化后:if (!isValid) return; // 提前处理异常,主流程保持简洁…...
【Vim】vim的简单使用
文章目录 1. vi的模式2. 按键使用说明2.1 一般命令模式光标移动替换和查找删除/复制/粘贴 2.2 编辑模式插入/替换 2.3 命令行模式保存/退出环境修改 3. vim的缓存4. vim可视区块5. vim多文件编辑6. vim多窗口功能7. vim关键词补全 1. vi的模式 一般命令模式:以vi打…...
【消息队列RocketMQ】一、RocketMQ入门核心概念与架构解析
在当今互联网技术飞速发展的时代,分布式系统的架构设计愈发复杂。消息队列作为分布式系统中重要的组件,在解耦应用、异步处理、削峰填谷等方面发挥着关键作用。RocketMQ 作为一款高性能、高可靠的分布式消息中间件,被广泛应用于各类互联网场景…...
hadoop分布式部署
1. 上传jdk和hadoop安装包到服务器 2. 解压压缩包 tar xf jdk1.8.0_112.tgz -C /usr/local/ tar xf hadoop-3.3.6.tar.gz -C /usr/local/3. 关闭防火墙 systemctl stop firewalld systemctl disable firewalld4. 修改配置文件 core-site.xml、hadoop-env.sh、yarn-env.sh、…...
C++面试题集合(附答案)
C全家桶 C基础 1. C和C有什么区别? 2. C语言的结构体和C的有什么区别? 3. C 语言的关键字 static 和 C 的关键字 static 有什么区别? 4. C 和 Java有什么核心区别? 5. C中,a和&a有什么区别? 6. …...
23种设计模式-结构型模式之装饰器模式(Java版本)
Java 装饰器模式(Decorator Pattern)详解 🎁 什么是装饰器模式? 装饰器模式是一种结构型设计模式,允许向一个对象动态添加新的功能,而不改变其结构。 🧱 你可以想象成在原有功能上“包裹”一…...
UE5的BumpOffset节点
BumpOffset 节点的基本概念 本质上,BumpOffset 节点通过扭曲或偏移纹理坐标来创造深度错觉。它基于视角方向和高度信息动态地调整纹理采样位置,使平面表面看起来具有凹凸感。这是一种称为视差映射(Parallax Mapping)的技术的实现。 当你从不同角度观察…...
从跌倒到领跑:北京亦庄机器人马拉松如何改写人机协作未来?
目录 一、当铁骨遇见马拉松精神 二、半马背后的硬核突破 三、赛事背后的科技博弈 四、当机器人走出实验室 跌倒者的荣光 清晨7:30的南海子公园,发令枪响瞬间——20台形态各异的机器人以千奇百怪的姿态冲出起跑线,有的像蹒跚学步的孩童,有的如专业运动员般矫健,更有机器…...
Internet Protocol
一、IP 1. 基本概念 IP定义:IP 是为计算机网络相互连接进行通信而设计的协议,它规定了网络设备如何标识和寻址,以及数据如何在网络中传输和路由。IP作用:主要负责在不同的网络之间转发数据包,使数据能够从源主机准确…...
Android学习之实战登录注册能力
我们可以从本地 Token 存储、时效管理、服务端通知联动、定时器优化四个维度深入展开 一、本地 Token 存储设计(基于 SharedPreferences) 1. 存储结构优化(包含时效性字段) // 定义存储类(封装SharedPreferences操作…...
【数据可视化-19】智能手机用户行为可视化分析
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
基于一致性哈希算法原理和分布式系统容错机制
一、传统取模算法的局限性分析 当使用User ID取模路由时,Pod挂断会导致以下问题: 数据雪崩效应:节点失效后所有请求需要重新计算取模值,导致缓存穿透和服务震荡服务不可用窗口:节点失效期间,原本路由到该节…...
[SpringBoot-1] 概述和快速入门(使用vscode)
1 SpringBoot 概念 SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程…...
学习笔记二十——Rust trait
🧩 Rust Trait 彻底搞懂版 👀 目标读者:对 Rust 完全陌生,但想真正明白 “Trait、Trait Bound、孤岛法则” 在做什么、怎么用、为什么这样设计。 🛠 方法: 先给“心里模型”——用生活类比把抽象概念掰开揉…...
llama factory
微调大模型可以像这样轻松… https://github.com/user-attachments/assets/e6ce34b0-52d5-4f3e-a830-592106c4c272 选择你的打开方式: 入门教程:https://zhuanlan.zhihu.com/p/695287607框架文档:https://llamafactory.readthedocs.io/zh-…...
机器学习 Day12 集成学习简单介绍
1.集成学习概述 1.1. 什么是集成学习 集成学习是一种通过组合多个模型来提高预测性能的机器学习方法。它类似于: 超级个体 vs 弱者联盟 单个复杂模型(如9次多项式函数)可能能力过强但容易过拟合 组合多个简单模型(如一堆1次函数)可以增强能力而不易过拟合 集成…...
基于 Spring Boot 瑞吉外卖系统开发(五)
基于 Spring Boot 瑞吉外卖系统开发(五) 删除分类 分类列表中每条分类信息右侧提供了一个“删除”按钮,当需要将已经存在的分类信息删除时,可以通过单击“删除”按钮实现。 请求路径为/category,携带参数id…...
PyTorch基础笔记
PyTorch张量 多维数组:张量可以是标量(0D)、向量(1D)、矩阵(2D)或更高维的数据(3D)。 数据类型:支持多种数据类型(如 float32, int64, bool 等&a…...
什么是 IDE?集成开发环境的功能与优势
原文:什么是 IDE?集成开发环境的功能与优势 | w3cschool笔记 (注意:此为科普文章,请勿标记为付费文章!且此文章并非我原创,不要标记为付费!) IDE 是什么? …...
基于大数据的房产估价解决方案
基于大数据的房产估价解决方案 一、项目背景与目标 1.1 背景 在房地产市场中,准确的房产估价至关重要。传统的房产估价方法往往依赖于估价师的经验和有限的数据样本,存在主观性强、效率低等问题。随着大数据技术的发展,大量的房产相关数据被积…...
基于深度学习的线性预测:创新应用与挑战
一、引言 1.1 研究背景 深度学习作为人工智能领域的重要分支,近年来在各个领域都取得了显著的进展。在线性预测领域,深度学习也逐渐兴起并展现出强大的潜力。传统的线性预测方法在处理复杂数据和动态变化的情况时往往存在一定的局限性。而深度学习凭借…...
WEMOS LOLIN32
ESP32是結合Wi-Fi和藍牙的32位元系統單晶片(SoC)與外接快閃記憶體的模組。許多廠商生產採用ESP32模組的控制板,最基本的ESP控制板包含ESP32模組、直流電壓轉換器和USB序列通訊介面IC。一款名為WEMOS LOLIN32的ESP32控制板具備3.7V鋰電池插座。…...
VSCode 扩展离线下载方法
学习自该文章,感谢作者! 2025 年 VSCode 插件离线下载攻略:官方渠道一键获取 - 知乎 获取扩展关键信息 方法一:官网获取 打开 VSCode 扩展官方网站 搜索要下载的扩展,以 CodeGeeX 为例,网址为…...
计算机视觉与深度学习 | RNN原理,公式,代码,应用
RNN(循环神经网络)详解 一、原理 RNN(Recurrent Neural Network)是一种处理序列数据的神经网络,其核心思想是通过循环连接(隐藏状态)捕捉序列中的时序信息。每个时间步的隐藏状态 ( h_t ) 不仅依赖当前输入 ( x_t ),还依赖前一时间步的隐藏状态 ( h_{t-1} ),从而实现…...
对于网络资源二级缓存的简单学习
缓存学习 前言认识缓存磁盘储存内存储存磁盘内存组合优化 具体实现WebCacheMD5签名 WebDownloadOperationWebDownloaderWebCombineOperation 总结 前言 在最近的写的仿抖音app中,遇到了当往下滑动视频后,当上方的视频进入复用池后,会自动清空…...
【计量地理学】实验六 地理属性空间插值
一、实验目的 本次实验的主要目的在于熟练掌握空间克里格法插值的理论基础,包括其核心概念和步骤,能够通过数据可视化和统计分析方法识别数据中的异常值,并且掌握数据正态性的检验方法,理解正态分布对克里格法的重要性࿰…...
26考研 | 王道 | 数据结构 | 第六章 图
第六章 图 文章目录 第六章 图6.1. 图的基本概念6.2. 图的存储6.2.1. 邻接矩阵6.2.2. 邻接表6.2.3. 十字链表、临接多重表6.2.4. 图的基本操作 6.3. 图的遍历6.3.1. 广度优先遍历6.3.2. 深度优先遍历6.3.3 图的遍历与连通性 6.4. 图的应用6.4.1. 最小生成树6.4.2. 无权图的单源…...
window.addEventListener 和 document.addEventListener
window.addEventListener 和 document.addEventListener 是 JavaScript 中绑定事件的两个常用方法,核心区别在于 绑定的对象不同,导致事件的作用范围、触发时机和适用场景不同。下面用最直白的语言和案例对比说明: 一、核心区别:…...
51单片机的原理图和PCB绘制
51单片机最小系统原理图 加了两个led灯和按键检测电路。 PCB中原件摆放位置 成品 资源链接:https://download.csdn.net/download/qq_61556106/90656365...
kotlin知识体系(五) :Android 协程全解析,从作用域到异常处理的全面指南
1. 什么是协程 协程(Coroutine)是轻量级的线程,支持挂起和恢复,从而避免阻塞线程。 2. 协程的优势 协程通过结构化并发和简洁的语法,显著提升了异步编程的效率与代码质量。 2.1 资源占用低(一个线程可运行多个协程)…...
数据通信学习笔记之OSPF其他内容3
对发送的 LSA 进行过滤 当两台路由器之间存在多条链路时,可以在某些链路上通过对发送的 LSA 进行过滤,减少不必要的重传,节省带宽资源。 通过对 OSPF 接口出方向的 LSA 进行过滤可以不向邻居发送无用的 LSA,从而减少邻居 LSDB 的…...
Kubernetes相关的名词解释API Server组件(9)
什么是API Server? API Server(kube-apiserver) 是 Kubernetes 的核心组件之一,负责管理整个集群的通信和操作入口。 API Server 的作用在整个 Kubernetes 集群的正常运作中至关重要,可以说它是整个系统的神经中枢。…...
[密码学实战]密码服务平台部署架构详解与学习路线
密码服务平台部署架构详解与学习路线 引言 在数字化转型的浪潮中,数据安全已成为企业生存的“生命线”。国密算法(SM2/SM3/SM4)作为我国自主研发的密码标准,正在政务、金融、医疗等领域加速落地。然而,构建一套高可用、高性能、合规的密码服务平台,仍需攻克架构设计、性…...