k3s完全兼容k8s,我解释一下是为什么:

因为k3s的底层数据结构(写入etcd/mysql/sqlite/dsqlite数据库的格式),是完全照搬k8s的数据结构。api完全兼容。 对外表现相同,底层数据相同,只是实现方式不同(举个例子: 一个爆炒大虾,一个油焖虾)。

我认为 k3s/k8s数据结构的3个用途:

  • 缓存从api中解析出来的参数,为了后面的处理逻辑更方便的去引用api的参数。
  • 方便响应api时,用marshal() 去生成json/protobuf序列化的数据
  • 方便写入数据库(etcd/mysql/sqlite)时,序列化为有序数据块

在k3s/k8s中,deploy、pod、service、Ingress、namespace、configmap等被成为资源。
yaml文件在定义一组(多组)资源的规格/约束条件的集合。

1 资源类型:

type TypeMeta struct {// rest api操作的资源类型:deployment/pod/servce/ingress/ns/pv/pvcKind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`// APIVersion defines the versioned schema of this representation of an object.// Servers should convert recognized schemas to the latest internal value, and// may reject unrecognized values.APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}

2 资源元数据:

资源元数据:与api相关、与调度器相关、与数据库相关。 什么叫相关? 直白点说:就是被读写

type ObjectMeta struct {// 在一个命名空间范围中,资源的名字(pod-https、pod-http、pod-web、sevice-reds、confiigmap-secrets-web)。  例如某个村里面(命名空间)不允许人重名,张三、李四Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`// 在创建yaml文件时,可以指定资源名称、也可以不指定资源名称(不指定时则 用资源类型-随机字符拼接,例如pod-nx7jsda,service-hlayjk0a),此变量就是k3s/k8s生成的默认资源名称GenerateName string `json:"generateName,omitempty" protobuf:"bytes,2,opt,name=generateName"`// 命名空间名称,例如default、filecoin、ingress-nginx。在同一个命名空间内,所有资源可互相感知存在。 在不同命名空间中,资源之间不能直接感知到其它命名空间的资源。Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`// url地址,client可以通过访问此地址,来只读到资源的内容。  对应另外一个命令是读写,kubectl edit pod pod-name// k3s/k8s在1.21 release会删除此变量(因为有读写api、(历史原因存在的)只读api显得很鸡肋),无视它即可。SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"`// k8s server在最终成功创建了资源后,会生成一个uuid给这资源,生成后,在资源的整个生命周期中不允许被修改。 (你可以理解为是身份证编号)UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"`// k3s/k8s 兼容多个api版本,即http/https rest api接口存在多个版本的路由,和多个版本对应的参数逻辑解析程序段// apiVersion: v1// apiVersion: v2// apps/v1beta1ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"`// 流水号Generation int64 `json:"generation,omitempty" protobuf:"varint,7,opt,name=generation"`// 资源被创建时的时间戳CreationTimestamp Time `json:"creationTimestamp,omitempty" protobuf:"bytes,8,opt,name=creationTimestamp"`// 资源被删除时的时间戳,例如kubectl delete pods pod-name 命令被执行到时的时间戳DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"`// 资源被删除时的宽限(给资源发让其退出的信号,等待资源关闭相关的系统资源后退出)时间(单位:秒),超过宽限时间则k3s/k8s会主动杀死资源DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"`// 给资源打标签: kubectl label node cka-node  disktype=gpu// 查看资源标签: kubectl get node --show-labels// 标签用途:用于更精细的去调度资源到指定的node,是k3/k8s为运维通讯提供的(管理/调度)扩展功能Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`// 注解://Annotations 允许在 Kubernetes 资源上附加任意的非标识性元数据,用来记录资源的一些属性。这些元数据主要是给工具或者库来提取信息,一般不会直接开放给用户。绝大多数基于 Kubernetes 的开源项目都不依赖于 DB,完全可以利用 Kubernetes 的能力,满足对 DB 的需求。对于需要持久化的数据,除了定义 CRD,另一种通用的做法就是将数据存储在 annotation 中。//由于 annotation 的定位是 Kubernetes 资源上附加任意的非标识性元数据,除了在 key 上有跟 label key 完全一样的限制外,在 value 上没有任何限制:可长可短,可结构化可非结构化,可包含任意字符。Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`// 包含足够的信息来让你确定一个对象,举个例子:你妈妈喊你吃饭时叫你小名:小张、狗子,你就知道是在叫你,而不用叫你的全名:张三丰、赵二狗OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"`// 资源在被删除之后,会写一个记录在这里切片中Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`// 资源属于的集群的名称。例如:易春雷老师(资源)是第二初级中学(集群名称)的优秀班主任, ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"`// ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"`
}type ManagedFieldsEntry struct {// Manager is an identifier of the workflow managing these fields.Manager string `json:"manager,omitempty" protobuf:"bytes,1,opt,name=manager"`// Operation is the type of operation which lead to this ManagedFieldsEntry being created.// The only valid values for this field are 'Apply' and 'Update'.Operation ManagedFieldsOperationType `json:"operation,omitempty" protobuf:"bytes,2,opt,name=operation,casttype=ManagedFieldsOperationType"`// APIVersion defines the version of this resource that this field set// applies to. The format is "group/version" just like the top-level// APIVersion field. It is necessary to track the version of a field// set because it cannot be automatically converted.APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"`// Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'// +optionalTime *Time `json:"time,omitempty" protobuf:"bytes,4,opt,name=time"`// Fields is tombstoned to show why 5 is a reserved protobuf tag.//Fields *Fields `json:"fields,omitempty" protobuf:"bytes,5,opt,name=fields,casttype=Fields"`// FieldsType is the discriminator for the different fields format and version.// There is currently only one possible value: "FieldsV1"FieldsType string `json:"fieldsType,omitempty" protobuf:"bytes,6,opt,name=fieldsType"`// FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.// +optionalFieldsV1 *FieldsV1 `json:"fieldsV1,omitempty" protobuf:"bytes,7,opt,name=fieldsV1"`// Subresource is the name of the subresource used to update that object, or// empty string if the object was updated through the main resource. The// value of this field is used to distinguish between managers, even if they// share the same name. For example, a status update will be distinct from a// regular update using the same manager name.// Note that the APIVersion field is not related to the Subresource field and// it always corresponds to the version of the main resource.Subresource string `json:"subresource,omitempty" protobuf:"bytes,8,opt,name=subresource"`
}

先写到这里,晚点补充其它数据结构。

3 服务:

type Service struct {          metav1.TypeMeta `json:",inline"`metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`// 存放servince.yaml文件定义的内容,被解析后的值Spec ServiceSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`// 服务/ingress的实时状态Status ServiceStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
} type ServicePort struct {// 服务对应的端口的(唯一)名字Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`// The IP protocol for this port. Supports "TCP", "UDP", and "SCTP".// Default is TCP.// +default="TCP"Protocol Protocol `json:"protocol,omitempty" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"`// The application protocol for this port.// This field follows standard Kubernetes label syntax.// Un-prefixed names are reserved for IANA standard service names (as perAppProtocol *string `json:"appProtocol,omitempty" protobuf:"bytes,6,opt,name=appProtocol"`// The port that will be exposed by this service.Port int32 `json:"port" protobuf:"varint,3,opt,name=port"`// 服务访问pod的端口TargetPort intstr.IntOrString `json:"targetPort,omitempty" protobuf:"bytes,4,opt,name=targetPort"`// linux node 真实portNodePort int32 `json:"nodePort,omitempty" protobuf:"varint,5,opt,name=nodePort"`
}type ServiceSpec struct {// 本服务暴露的端口列表Ports []ServicePort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"port" protobuf:"bytes,1,rep,name=ports"`// 服务选择器:一组标签,用于匹配符合标签的资源Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"`// 随机ip地址(kubectl cli未指定的话),指定本服务的ip地址ClusterIP string `json:"clusterIP,omitempty" protobuf:"bytes,3,opt,name=clusterIP"`// 随机ip地址列表(kubectl cli未指定的话),指定本服务的ip(多个)地址ClusterIPs []string `json:"clusterIPs,omitempty" protobuf:"bytes,18,opt,name=clusterIPs"`// 服务被暴露的方式:ClusterIP/NodePort/LoadBalancerType ServiceType `json:"type,omitempty" protobuf:"bytes,4,opt,name=type,casttype=ServiceType"`// externalIPs is a list of IP addresses for which nodes in the cluster// will also accept traffic for this service.  These IPs are not managed by// Kubernetes.  The user is responsible for ensuring that traffic arrives// at a node with this IP.  A common example is external load-balancers// that are not part of the Kubernetes system.// +optionalExternalIPs []string `json:"externalIPs,omitempty" protobuf:"bytes,5,rep,name=externalIPs"`// Supports "ClientIP" and "None". Used to maintain session affinity.// Enable client IP based session affinity.// Must be ClientIP or None.// Defaults to None.// More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies// +optionalSessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty" protobuf:"bytes,7,opt,name=sessionAffinity,casttype=ServiceAffinity"`// Only applies to Service Type: LoadBalancer// LoadBalancer will get created with the IP specified in this field.// This feature depends on whether the underlying cloud-provider supports specifying// the loadBalancerIP when a load balancer is created.// This field will be ignored if the cloud-provider does not support the feature.// +optionalLoadBalancerIP string `json:"loadBalancerIP,omitempty" protobuf:"bytes,8,opt,name=loadBalancerIP"`// If specified and supported by the platform, this will restrict traffic through the cloud-provider// load-balancer will be restricted to the specified client IPs. This field will be ignored if the// cloud-provider does not support the feature."// More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/// +optionalLoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty" protobuf:"bytes,9,opt,name=loadBalancerSourceRanges"`// externalName is the external reference that discovery mechanisms will// return as an alias for this service (e.g. a DNS CNAME record). No// proxying will be involved.  Must be a lowercase RFC-1123 hostname// (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName".// +optionalExternalName string `json:"externalName,omitempty" protobuf:"bytes,10,opt,name=externalName"`// externalTrafficPolicy denotes if this Service desires to route external// traffic to node-local or cluster-wide endpoints. "Local" preserves the// client source IP and avoids a second hop for LoadBalancer and Nodeport// type services, but risks potentially imbalanced traffic spreading.// "Cluster" obscures the client source IP and may cause a second hop to// another node, but should have good overall load-spreading.// +optionalExternalTrafficPolicy ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty" protobuf:"bytes,11,opt,name=externalTrafficPolicy"`// 服务监控侦测(节点)端口,只在LoadBalancer / externalTrafficPolicy 模式时有效HealthCheckNodePort int32 `json:"healthCheckNodePort,omitempty" protobuf:"bytes,12,opt,name=healthCheckNodePort"`// publishNotReadyAddresses indicates that any agent which deals with endpoints for this// Service should disregard any indications of ready/not-ready.// The primary use case for setting this field is for a StatefulSet's Headless Service to// propagate SRV DNS records for its Pods for the purpose of peer discovery.// The Kubernetes controllers that generate Endpoints and EndpointSlice resources for// Services interpret this to mean that all endpoints are considered "ready" even if the// Pods themselves are not. Agents which consume only Kubernetes generated endpoints// through the Endpoints or EndpointSlice resources can safely assume this behavior.// +optionalPublishNotReadyAddresses bool `json:"publishNotReadyAddresses,omitempty" protobuf:"varint,13,opt,name=publishNotReadyAddresses"`// sessionAffinityConfig contains the configurations of session affinity.// +optionalSessionAffinityConfig *SessionAffinityConfig `json:"sessionAffinityConfig,omitempty" protobuf:"bytes,14,opt,name=sessionAffinityConfig"`// TopologyKeys is tombstoned to show why 16 is reserved protobuf tag.//TopologyKeys []string `json:"topologyKeys,omitempty" protobuf:"bytes,16,opt,name=topologyKeys"`// IPFamily is tombstoned to show why 15 is a reserved protobuf tag.// IPFamily *IPFamily `json:"ipFamily,omitempty" protobuf:"bytes,15,opt,name=ipFamily,Configcasttype=IPFamily"`// IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this// service. This field is usually assigned automatically based on cluster// configuration and the ipFamilyPolicy field. If this field is specified// manually, the requested family is available in the cluster,// and ipFamilyPolicy allows it, it will be used; otherwise creation of// the service will fail. This field is conditionally mutable: it allows// for adding or removing a secondary IP family, but it does not allow// changing the primary IP family of the Service. Valid values are "IPv4"// and "IPv6".  This field only applies to Services of types ClusterIP,// NodePort, and LoadBalancer, and does apply to "headless" services.// This field will be wiped when updating a Service to type ExternalName.//// This field may hold a maximum of two entries (dual-stack families, in// either order).  These families must correspond to the values of the// clusterIPs field, if specified. Both clusterIPs and ipFamilies are// governed by the ipFamilyPolicy field.// +listType=atomic// +optionalIPFamilies []IPFamily `json:"ipFamilies,omitempty" protobuf:"bytes,19,opt,name=ipFamilies,casttype=IPFamily"`// IPFamilyPolicy represents the dual-stack-ness requested or required by// this Service. If there is no value provided, then this field will be set// to SingleStack. Services can be "SingleStack" (a single IP family),// "PreferDualStack" (two IP families on dual-stack configured clusters or// a single IP family on single-stack clusters), or "RequireDualStack"// (two IP families on dual-stack configured clusters, otherwise fail). The// ipFamilies and clusterIPs fields depend on the value of this field. This// field will be wiped when updating a service to type ExternalName.// +optionalIPFamilyPolicy *IPFamilyPolicyType `json:"ipFamilyPolicy,omitempty" protobuf:"bytes,17,opt,name=ipFamilyPolicy,casttype=IPFamilyPolicyType"`// allocateLoadBalancerNodePorts defines if NodePorts will be automatically// allocated for services with type LoadBalancer.  Default is "true". It// may be set to "false" if the cluster load-balancer does not rely on// NodePorts.  If the caller requests specific NodePorts (by specifying a// value), those requests will be respected, regardless of this field.// This field may only be set for services with type LoadBalancer and will// be cleared if the type is changed to any other type.// This field is beta-level and is only honored by servers that enable the ServiceLBNodePortControl feature.// +featureGate=ServiceLBNodePortControl// +optionalAllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty" protobuf:"bytes,20,opt,name=allocateLoadBalancerNodePorts"`// loadBalancerClass is the class of the load balancer implementation this Service belongs to.// If specified, the value of this field must be a label-style identifier, with an optional prefix,// e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users.// This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load// balancer implementation is used, today this is typically done through the cloud provider integration,// but should apply for any default implementation. If set, it is assumed that a load balancer// implementation is watching for Services with a matching class. Any default load balancer// implementation (e.g. cloud providers) should ignore Services that set this field.// This field can only be set when creating or updating a Service to type 'LoadBalancer'.// Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type.// +featureGate=LoadBalancerClass// +optionalLoadBalancerClass *string `json:"loadBalancerClass,omitempty" protobuf:"bytes,21,opt,name=loadBalancerClass"`// InternalTrafficPolicy specifies if the cluster internal traffic// should be routed to all endpoints or node-local endpoints only.// "Cluster" routes internal traffic to a Service to all endpoints.// "Local" routes traffic to node-local endpoints only, traffic is// dropped if no node-local endpoints are ready.// The default value is "Cluster".// +featureGate=ServiceInternalTrafficPolicy// +optionalInternalTrafficPolicy *ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"`
}type LoadBalancerStatus struct {// ingress-nginx是组路由规则,这里是路由规则列表Ingress []LoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"`
} type ServiceStatus struct {// ingress 状态LoadBalancer LoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"`// Current service state// +optional// +patchMergeKey=type// +patchStrategy=merge// +listType=map// +listMapKey=typeConditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,2,rep,name=conditions"`
}type LoadBalancerIngress struct {// IP is set for load-balancer ingress points that are IP based// (typically GCE or OpenStack load-balancers)// +optionalIP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"`// Hostname is set for load-balancer ingress points that are DNS based// (typically AWS load-balancers)// +optionalHostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"`// Ports is a list of records of service ports// If used, every port defined in the service should have an entry in it// +listType=atomic// +optionalPorts []PortStatus `json:"ports,omitempty" protobuf:"bytes,4,rep,name=ports"`
}type PortStatus struct {// Port is the port number of the service port of which status is recorded herePort int32 `json:"port" protobuf:"varint,1,opt,name=port"`// Protocol is the protocol of the service port of which status is recorded here// The supported values are: "TCP", "UDP", "SCTP"Protocol Protocol `json:"protocol" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"`Error *string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"`
}

4 service/ingress暴露端口映射关系:

5 挂载容器运行时:

“/var/run/netns”, “/run/containerd”, “/run/xtables.lock” 是三个linux系统内核特殊目录,用于与内核虚拟化接口进行交互

6 port、nodeport、targetport的关系如下:

  • port: 服务(被k8s集群以外的组件)访问的端口
  • targetPort: 容器内部通讯端口
  • nodePort:: k8s外部的组件调用pod的一种方式叫NodePort,另外一种方式是LoadBalaner

《k3s 源码解析4 ---- k3s重要数据结构》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. UML:概要设计,用什么画我的类图?
  2. 计算机及网络应用基础思维导图_思维导图在生物教学中的应用
  3. 四象限法推导lm曲线_【老王讲放射】四象限理论
  4. 面向对象一类与对象的概念与特性
  5. Java学习lesson 14
  6. 不使用框架的web项目中配置log4j
  7. C1000k 新思路:用户态 TCP/IP 协议栈
  8. Java基础:常用IO流
  9. 1360E. Polygon
  10. Myeclipse 使用JUnit 进行单元测试
  11. 数据分析学习笔记—文件处理与pdf处理
  12. 散粉在哪个步骤用_无限回购的散粉
  13. PyQt5 电报实时聊天软件 BB-Telegram Pt.0
  14. Caffe教程:训练自己的网络结构来分类。
  15. 机器视觉工程师之关于程序员的头发
  16. 百度自动php推送蜘蛛怎么不来访问,使用代码向百度蜘蛛主动推送链接
  17. 新西兰的中国新移民现状:缺乏安全感和归属感
  18. 网络设备器出现黄色感叹号有线链接无线链接选项均消失
  19. nginx平台初探(100%)
  20. 新颖的自我介绍_精选简单新颖的自我介绍

热门文章

  1. 淘宝API 获取购买到的商品订单详情
  2. 美国计算机科学排名前三大学,美国计算机科学专业大学排名(2021 USNEWS)
  3. Java三(运算符 )
  4. 《微信小程序》 开源项目
  5. RadRails插件在 MyEclipse的安装(转http://wayfarer.blog.51cto.com/1300239/329290)
  6. 用matlab实现蛇形,matlab蛇形机械手仿真建模
  7. halcon图像灰度操作
  8. 荣耀7c升鸿蒙,荣耀也能升级!鸿蒙所需配置曝光:麒麟710起步
  9. 2021谷歌算法排名因素大全
  10. 郊区春游(NC16122)状压dp