K8s运维-高级网络策略介绍

1

什么是NetworkPolicy?


如果你希望在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量, 则你可以考虑为集群中特定应用使用 Kubernetes 网络策略(NetworkPolicy)。NetworkPolicy 是一种以应用为中心的结构,允许你设置如何允许 Pod 与网络上的各类网络“实体” (我们这里使用实体以避免过度使用诸如“端点”和“服务”这类常用术语, 这些术语在 Kubernetes 中有特定含义)通信。

Pod 可以通信的 Pod 是通过如下三个标识符的组合来辩识的:

  1. 其他被允许的 Pods(例外:Pod 无法阻塞对自身的访问)

  1. 被允许的名字空间

  1. IP 组块(例外:与 Pod 运行所在的节点的通信总是被允许的, 无论 Pod 或节点的 IP 地址)

在定义基于 Pod 或名字空间的 NetworkPolicy 时,你会使用 选择算符 来设定哪些流量 可以进入或离开与该算符匹配的 Pod。

同时,当基于 IP 的 NetworkPolicy 被创建时,我们基于 IP 组块(CIDR 范围) 来定义策略。

前置条件

网络策略通过网络插件 来实现。要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。

Pod 隔离的两种类型

Pod 有两种隔离: 出口的隔离和入口的隔离。它们涉及到可以建立哪些连接。这里的“隔离”不是绝对的,而是意味着“有一些限制”。另外的,“非隔离方向”意味着在所述方向上没有限制。这两种隔离(或不隔离)是独立声明的, 并且都与从一个 Pod 到另一个 Pod 的连接有关。

默认情况下,一个 Pod 的出口是非隔离的,即所有外向连接都是被允许的。如果有任何的 NetworkPolicy 选择该 Pod 并在其 policyTypes 中包含 “Egress”,则该 Pod 是出口隔离的, 我们称这样的策略适用于该 Pod 的出口。当一个 Pod 的出口被隔离时, 唯一允许的来自 Pod 的连接是适用于出口的 Pod 的某个 NetworkPolicy 的 egress 列表所允许的连接。这些 egress 列表的效果是相加的。

默认情况下,一个 Pod 对入口是非隔离的,即所有入站连接都是被允许的。如果有任何的 NetworkPolicy 选择该 Pod 并在其 policyTypes 中包含 “Ingress”,则该 Pod 被隔离入口, 我们称这种策略适用于该 Pod 的入口。当一个 Pod 的入口被隔离时,唯一允许进入该 Pod 的连接是来自该 Pod 节点的连接和适用于入口的 Pod 的某个 NetworkPolicy 的 ingress 列表所允许的连接。这些 ingress 列表的效果是相加的。

网络策略是相加的,所以不会产生冲突。如果策略适用于 Pod 某一特定方向的流量, Pod 在对应方向所允许的连接是适用的网络策略所允许的集合。因此,评估的顺序不影响策略的结果。

要允许从源 Pod 到目的 Pod 的连接,源 Pod 的出口策略和目的 Pod 的入口策略都需要允许连接。如果任何一方不允许连接,建立连接将会失败。

2

NetworkPolicy配置详解


参阅 NetworkPolicy 来了解资源的完整定义。

下面是一个 NetworkPolicy 的示例:

apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: test-network-policynamespace: defaultspec:podSelector: matchLabels:    role: dbpolicyTypes:-Ingress-Egressingress:-from: - ipBlock:      cidr: 172.17.0.0/16      except:      - 172.17.1.0/24 - namespaceSelector:      matchLabels:        project: myproject - podSelector:      matchLabels:        role: frontend ports: - protocol: TCP    port: 6379egress:-to: - ipBlock:      cidr: 10.0.0.0/24 ports: - protocol: TCP    port: 5978

  • 说明: 除非选择支持网络策略的网络解决方案,否则将上述示例发送到API服务器没有任何效果。

必需字段:与所有其他的 Kubernetes 配置一样,NetworkPolicy 需要 apiVersion、 kind 和 metadata 字段。关于配置文件操作的一般信息,请参考使用 ConfigMap 配置容器, 和对象管理。

spec:NetworkPolicy 规约 中包含了在一个名字空间中定义特定网络策略所需的所有信息。

podSelector:每个 NetworkPolicy 都包括一个 podSelector,它对该策略所 适用的一组 Pod 进行选择。示例中的策略选择带有 "role=db" 标签的 Pod。空的 podSelector 选择名字空间下的所有 Pod。

policyTypes: 每个 NetworkPolicy 都包含一个 policyTypes 列表,其中包含 Ingress 或 Egress 或两者兼具。policyTypes 字段表示给定的策略是应用于 进入所选 Pod 的入站流量还是来自所选 Pod 的出站流量,或两者兼有。如果 NetworkPolicy 未指定 policyTypes 则默认情况下始终设置 Ingress;如果 NetworkPolicy 有任何出口规则的话则设置 Egress。

ingress: 每个 NetworkPolicy 可包含一个 ingress 规则的白名单列表。每个规则都允许同时匹配 from 和 ports 部分的流量。示例策略中包含一条 简单的规则:它匹配某个特定端口,来自三个来源中的一个,第一个通过 ipBlock 指定,第二个通过 namespaceSelector 指定,第三个通过 podSelector 指定。

egress: 每个 NetworkPolicy 可包含一个 egress 规则的白名单列表。每个规则都允许匹配 to 和 port 部分的流量。该示例策略包含一条规则, 该规则将指定端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

所以,该网络策略示例:

  1. 隔离 "default" 名字空间下 "role=db" 的 Pod (如果它们不是已经被隔离的话)。

  1. (Ingress 规则)允许以下 Pod 连接到 "default" 名字空间下的带有 "role=db" 标签的所有 Pod 的 6379 TCP 端口:

  • "default" 名字空间下带有 "role=frontend" 标签的所有 Pod

  • 带有 "project=myproject" 标签的所有名字空间中的 Pod

  • IP 地址范围为 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255 (即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16)

  1. (Egress 规则)允许从带有 "role=db" 标签的名字空间下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口的连接。

3

NetworkPolicy注意事项


在配置网络策略时,有很多细节需要注意,比如上述的示例中,一段关于ingress的from配置:

 - from:    - ipBlock:        cidr: 172.17.0.0/16        except:        - 172.17.1.0/24    - namespaceSelector:        matchLabels:          project: myproject    - podSelector:        matchLabels:          role: frontend#namespaceSelector和podSelector是或的关系,表示两个条件满足一个就可以

需要注意的是在ipBlock、namespaceSelector和podSelector前面都有一个“-”,如果前面没有这个横杠将是另外一个完全不同的概念。可以看一下下面的示例:

- from:    - ipBlock:        cidr: 172.17.0.0/16        except:        - 172.17.1.0/24    - namespaceSelector:        matchLabels:          project: myproject      podSelector:        matchLabels:          role: frontend#namespaceSelector和podSelector是并且的关系,表示两个条件都满足

此时的namespaceSelector有“-”,podSelector没有“-”,那此时的配置,代表的含义是允许具有user=alice标签的Namespace下,并且具有role=client标签的所有Pod访问,namespaceSelector和podSelector是且的关系。那我们继续看一下示例:

ingress:  - from:    - namespaceSelector:        matchLabels:          user: alice    - podSelector:        matchLabels:          role: client

此时的namespaceSelector和podSelector都有“-”,配置的含义是允许具有user=alice标签的Namespace下的所有Pod和当前Namespace下具有role=client标签的Pod访问,namespaceSelector和podSelector是或的关系。

除了上述的差别外,在配置ipBlock时,可能也会出现差异性。因为我们在接收或者发送流量时,很有可能伴随着数据包中源IP和目标IP的重写,也就是SNAT和DNAT,此时会造成流量的目标IP和源IP与配置的ipBlock出现了差异性,造成网络策略不生效,所以在配置IPBlock时,需要确认网络交换中是否存在源目地址转换,并且IPBlock最好不要配置Pod的IP,因为Pod发生重建时,它的IP地址一般就会发生变更,所以IPBlock一般用于配置集群的外部IP。

4

NetworkPolicy示例1:隔离中间件服务


  1. 有一个项目,它有自己数据库MySQL和缓存Redis中间件,我们只希望这个项目的应用能够访问该中间件

  1. 假如有一个项目需要通过Ingress进行对外发布,我们想要除了Ingress外,其他任何Namespace下的Pod都不能访问该项目。

假设有一个项目叫nw-demo,里面部署了三个微服务,分别是MySQL、Redis和Nginx。现需要对MySQL、Redis、Nginx进行隔离,分别实现如下效果:

  • MySQL、Redis只能被该Namespace下的Pod访问;

  • Nginx可以被Ingress-nginx命名空间下的Pod和该Namespace下的Pod访问;

首先创建该项目所用的Namespace(如果已经存在,或者用其他Namespace测试,也可以不创建):

[root@k8s-master01 ~]# kubectl create ns nw-demonamespace/nw-demo created

创建MySQL服务,MySQL以容器启动时,必须配置root的密码,或者设置密码为空,所以需要设置一个MYSQL_ROOT_PASSWORD的变量:

[root@k8s-master01 ~]# kubectl create deploy mysql --image=registry.cn-beijing.aliyuncs.com/mysql:5.7.23 -n nw-demodeployment.apps/mysql created# 设置密码[root@k8s-master01 ~]# kubectl  set env deploy/mysql  MYSQL_ROOT_PASSWORD=mysql -n nw-demodeployment.apps/mysql env updated

创建Redis服务:

[root@k8s-master01 ~]# kubectl create deploy redis --image=registry.cn-beijing.aliyuncs.com/redis:5.0.9-alpine3.11 -n nw-demodeployment.apps/redis created

确认容器是否启动:

[root@k8s-master01 ~]# kubectl  get po -n nw-demo -owideNAME                     READY   STATUS    RESTARTS   AGE    IP               NODE                         NOMINATEDNODE   READINESSGATESmysql-64478b7cf9-qrczt   1/1     Running   0          2m9s   192.170.21.240   k8s-node03.example.local     <none>           <none>redis-5f69645dc-vvnnj    1/1     Running   0          41s    192.162.55.68    k8s-master01.example.local   <none>           <none>

在没有配置任何网络策略时,测试下网络的连通性,可以在任意Kubernetes节点上执行telnet命令:

[root@k8s-master01 ~]# telnet 192.170.21.240 3306Trying 192.170.21.240...Connected to 192.170.21.240.Escape character is'^]'.J/}REGq yfCo@Gjumysql_native_passwordConnection closed by foreign host.[root@k8s-master01 ~]# telnet 192.162.55.68 6379Trying 192.162.55.68...Connected to 192.162.55.68.Escape character is'^]'.quit+OKConnection closed by foreign host.

注意: 本文章进行测试的IP和Pod名字可能与实际测试的不一致,需要与实际情况为准

可以看到此时的网络都是可以通信的。接下来可以根据Pod的标签进行网络隔离,首先查看一下Pod的标签:

[root@k8s-master01 ~]# kubectl  get po -n nw-demo --show-labelsNAME                     READY   STATUS    RESTARTS   AGE     LABELSmysql-64478b7cf9-qrczt   1/1     Running   0          5m15s   app=mysql,pod-template-hash=64478b7cf9redis-5f69645dc-vvnnj    1/1     Running   0          3m47s   app=redis,pod-template-hash=5f69645dc

然后根据标签配置网络策略,本示例的配置将MySQL和Redis进行了拆分,配置了两个网络策略,当然也可以给两个Pod配置一个相同的标签,这样就可以使用同一个网络策略进行限制。但是在生产环境中,并不推荐使用同一个网络策略,因为有时候需要更细粒度的策略,同一个网络策略可能会有局限性,也会导致配置失败,所以本示例采用分开的网络策略进行配置:

[root@k8s-master01~]# vim mysql-redis-nw.yamlapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: mysql-npnamespace: nw-demospec:podSelector: matchLabels:    app: mysqlpolicyTypes: -Ingressingress: -from:  - namespaceSelector:      matchLabels:        access-nw-mysql-redis: "true" ports:  - protocol: TCP    port: 3306---apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: redis-npnamespace: nw-demospec:podSelector: matchLabels:    app: redis policyTypes: -Ingressingress: -from:  - namespaceSelector:      matchLabels:        access-nw-mysql-redis: "true" ports:  - protocol: TCP    port: 6379

该yaml含有两个NetworkPolicy,其中mysql-np是对具有app=mysql标签的Pod进行管理,redis-np是对具有app=redis标签的Pod进行管理。但是需要注意的是该网络策略的ingress from是以namespaceSelector的标签进行匹配的,并非podSelector,或者是两者的结合。因为在生产环境中,同一个Namespace下可能会有很多不同类型、不同标签的Pod,并且它们可能并不具有一个相同的标签,所以如果通过podSelector进行选择,可能会比较麻烦,因为Pod一旦创建,对其标签的修改是很不方便的(apps/v1一旦创建就不可修改)。而使用namespaceSelector另一个好处是,可以很方便的对某个Namespace下的Pod进行管控,直接给指定Namespace添加标签即可,当然,如果需要更细粒度的管控,也可以结合podSelector使用。

接下来创建该NetworkPolicy:

[root@k8s-master01 ~]# kubectl  create -f mysql-redis-nw.yaml -n nw-demonetworkpolicy.networking.k8s.io/mysql-np creatednetworkpolicy.networking.k8s.io/redis-np created[root@k8s-master01 ~]# kubectl  get networkpolicy -n nw-demoNAME       POD-SELECTOR   AGEmysql-np   app=mysql      18sredis-np   app=redis      18s

创建后宿主机和任何Pod都已不能访问该Namespace下的MySQL和Redis:

[root@k8s-master01 ~]# telnet 192.170.21.240 3306Trying 192.170.21.240...^C[root@k8s-master01 ~]# telnet 192.162.55.68 6379Trying 192.162.55.68...^C

在nw-demo命名空间下创建一个用于测试连通性的工具,然后进行测试,也是不能访问该服务的:

[root@k8s-master01 ~]# kubectl  run -ti debug-tools --image=registry.cn-beijing.aliyuncs.com/debug-tools:latest -n nw-demoIf you don't see a command prompt, try pressing enter.(09:43 debug-tools:/) (09:43 debug-tools:/) curl 192.170.21.240:3306 --connect-timeout 3curl: (28) Connection timed out after 3001 milliseconds(28 09:44 debug-tools:/) exitexitSession ended, resume using 'kubectl attach debug-tools -c debug-tools -i -t' command when the pod is running

由于之前的from配置的是namespaceSelector,所以如果想要某一个Namespace下的Pod能够访问,直接给该Namespace添加一个NetworkPolicy中配置的标签即可,比如允许nw-demo命名空间下的所以Pod访问该NetworkPolicy隔离的服务:

[root@k8s-master01 ~]# kubectl label ns nw-demo access-nw-mysql-redis=truenamespace/nw-demo labeled

使用nw-demo命名空间下的debug-tools再次测试:

[root@k8s-master01 ~]# kubectlexec-tidebug-tools-nnw-demo--curl 192.170.21.240:33065.7.23      ,)ar\jÿÿ󿿕~V7gKo"Zmysql_native_passwordotpacketsoutoforder

此时nw-demo下的Pod已经可以访问MySQL和Redis,可以对其他Namespace下的Pod进行测试,比如在default命名空间进行测试:

[root@k8s-master01 ~]# kubectl  run -ti debug-tools --image=registry.cn-beijing.aliyuncs.com/debug-tools:latest -n default If you don't see a command prompt, try pressing enter.(09:46 debug-tools:/) (09:46 debug-tools:/) curl 192.170.21.240:3306 --connect-timeout 3curl: (28) Connection timed out after 3001 milliseconds(28 09:47 debug-tools:/) exitexitSession ended, resume using 'kubectl attach debug-tools -c debug-tools -i -t' command when the pod is running

可以看到此时default命名空间下的Pod并不能访问nw-demo的服务,如果想要MySQL和Redis对default命名空间开放,只需要添加一个access-nw-mysql-redis=true的标签即可。

相对于传统架构,对中间件的访问限制,在Kubernetes中实现同样的效果,可能配置更加方便且易于管理。

5

NetworkPolicy示例2:服务发布限制


一般情况下,一个项目的服务发布,会把域名的根路径指向前端应用,接口路径指向对应的网关或者微服务。假设现在创建一个Nginx服务充当前端页面,配置网络策略只让Ingress Controller访问该应用:

# 创建应用[root@k8s-master01 ~]# kubectl  create deploy nginx --image=registry.cn-beijing.aliyuncs.com/nginx:latest -n nw-demodeployment.apps/nginx created# 暴露服务[root@k8s-master01 ~]# kubectl expose deploy nginx -n nw-demo --port=80service/nginx exposed# 查看创建的服务[root@k8s-master01 ~]# kubectl  get svc,po -n nw-demo -l app=nginxNAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGEservice/nginx   ClusterIP   10.102.194.2   <none>        80/TCP    31sNAME                         READY   STATUS    RESTARTS   AGEpod/nginx-65bf9b498b-smwhg   1/1     Running   0          61s

在没有任何网络策略的情况下,该服务可以被任何Pod访问:

[root@k8s-master01 ~]# kubectl  exec debug-tools -- curl -Is nginx.nw-demoHTTP/1.1 200 OKServer: nginx/1.19.6Date: Sun, 10 Apr 2022 10:13:15 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 15 Dec 2020 13:59:38 GMTConnection: keep-aliveETag: "5fd8c14a-264"Accept-Ranges: bytes[root@k8s-master01 ~]# kubectl  -n nw-demo exec debug-tools -- curl -Is nginx.nw-demoHTTP/1.1 200 OKServer: nginx/1.19.6Date: Sun, 10 Apr 2022 10:13:34 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 15 Dec 2020 13:59:38 GMTConnection: keep-aliveETag: "5fd8c14a-264"Accept-Ranges: bytes

配置网络策略只让Ingress Controller访问该服务:

[root@k8s-master01~]# vim nginx-nw.yamlapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: nginx-npnamespace: nw-demospec:podSelector: matchLabels:    app: nginxpolicyTypes: -Ingressingress: -from:  - namespaceSelector:      matchLabels:        app.kubernetes.io/name: ingress-nginx    podSelector:      matchLabels:        "app.kubernetes.io/name": ingress-nginx  - podSelector: {} ports:  - protocol: TCP    port: 80

注意: 该条策略对具有app=nginx标签的Pod生效,只让具有app.kubernetes.io/name=ingress-nginx标签的Namespace下的具有app.kubernetes.io/name=ingress-nginx标签的Pod访问,同时还有一个允许当前Namespace下的Pod访问的策略- podSelector: {} 。需要注意的是,读者的集群中已经安装了相关Ingress,并且需要根据实际的标签进行更改,如果读者集群目前并未安装Ingress,可以完成Ingress的学习后,再来测试该实验。

创建该NetworkPolicy,并测试连通性:

[root@k8s-master01 ~]# kubectl  create -f nginx-nw.yaml networkpolicy.networking.k8s.io/nginx-np created# 没有被允许的命名空间无法访问[root@k8s-master01 ~]# kubectl  exec debug-tools -- curl --connect-timeout 2 -Is nginx.nw-democommand terminated withexit code 28# 允许范围内的Pod可以访问[root@k8s-master01 ~]# kubectl  exec debug-tools -n nw-demo -- curl --connect-timeout 2 -Is nginx.nw-demoHTTP/1.1200 OKServer: nginx/1.19.6Date: Sun, 10 Apr 202210:16:54 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 15Dec202013:59:38 GMTConnection: keep-aliveETag: "5fd8c14a-264"Accept-Ranges: bytes[root@k8s-master01 ~]# kubectl get ns -l app.kubernetes.io/name=ingress-nginxNAME            STATUS   AGEingress-nginx   Active   9d[root@k8s-master01 ~]# kubectl get pod -n ingress-nginx -l app.kubernetes.io/name=ingress-nginxNAME                                        READY   STATUS    RESTARTS   AGEingress-nginx-controller-79cd59dd94-qfq5n   1/1     Running   0          4m14s[root@k8s-master01 ~]# kubectl label node k8s-master02.example.local ingress=true[root@k8s-master01 ~]# kubectl get pod -n ingress-nginx -o wideNAME                                       READY   STATUS    RESTARTS   AGE    IP             NODE                         NOMINATED NODE   READINESS GATESingress-nginx-controller-7f9fbd446-58bw2   1/1     Running   0          102s   172.31.3.112   k8s-node02.example.local     <none>           <none>ingress-nginx-controller-7f9fbd446-hmhng   1/1     Running   0          45s    172.31.3.102   k8s-master02.example.local   <none>           <none>ingress-nginx-controller-7f9fbd446-ps5hf   1/1     Running   0          45s    172.31.3.113   k8s-node03.example.local     <none>           <none>#在node上测试有问题,标签打到master上测试正常[root@k8s-master01 ~]# kubectl exec ingress-nginx-controller-7f9fbd446-hmhng -n ingress-nginx -- curl -Is nginx.nw-demoHTTP/1.1200 OKServer: nginx/1.19.6Date: Sun, 10 Apr 202211:27:24 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 15Dec202013:59:38 GMTConnection: keep-aliveETag: "5fd8c14a-264"Accept-Ranges: bytes

可以看到Ingress Controller和该Namespace下的Pod可以访问,其他Namespace不可以访问。此时可以创建一个Ingress,然后用域名测试:

[root@k8s-master01 ~]# kubectl  create ingress nginx  --rule="testnp.com/*=nginx:80" -n nw-demoingress.networking.k8s.io/nginx created[root@k8s-master01 ~]# curl -H "Host:testnp.com" 172.31.3.102<head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx</center></body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/453.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【1615. 最大网络秩】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; n 座城市和一些连接这些城市的道路 roads 共同组成一个基础设施网络。每个 roads[i] [ai, bi] 都表示在城市 ai 和 bi 之间有一条双向道路。 两座不同城市构成的 城市对 的 网络秩 定义为&#xff…

从0到1构建springboot web应用镜像并使用容器部署

文章目录一、生成镜像的两种方法1.1、使用commit生成镜像1.1.1、拉取Centos基础镜像1.1.2、启动Centos容器并安装Go1.1.3、commit生成新镜像1.1.4、使用新镜像验证Golang环境1.2、使用Dockerfile生成镜像二、基于Dockerfile生成一个springboot镜像2.1、准备springboot应用jar包…

python自动化办公(一)

本文代码参考其他教程书籍实现。 文章目录文件读写open函数读取文本文件写入文本文件文件和目录操作使用os库使用shutil库文件读写 open函数 open函数有8个参数&#xff0c;常用前4个&#xff0c;除了file参数外&#xff0c;其他参数都有默认值。file指定了要打开的文件名称&a…

FreeRTOS系列第1篇---为什么选择FreeRTOS?

1.为什么学习RTOS&#xff1f; 作为基于ARM7、Cortex-M3硬件开发的嵌入式工程师&#xff0c;我一直反对使用RTOS。不仅因为不恰当的使用RTOS会给项目带来额外的稳定性风险&#xff0c;更重要的是我认为绝大多数基于ARM7、Cortex-M3硬件的项目&#xff0c;还没复杂到使用RTOS的地…

【华为机试真题详解 Python实现】最差产品奖【2023 Q1 | 100分】

文章目录 前言题目描述输入描述输出描述示例 1题目解析参考代码前言 《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能…

SpringBoot和Spring AOP默认动态代理方式

SpringBoot和Spring AOP默认动态代理方式 目录SpringBoot和Spring AOP默认动态代理方式1. springboot 2.x 及以上版本2. Springboot 1.x3.SpringBoot 2.x 为何默认使用 CglibSpring 5.x中AOP默认依旧使用JDK动态代理SpringBoot 2.x开始&#xff0c;AOP为了解决使用JDK动态代理可…

做技术,最忌讳东张西望

又好长时间没更新&#xff0c;研二了&#xff0c;忙着做实验、写论文、发论文&#xff0c;再加上给我导做一些事情&#xff08;都习惯了&#xff0c;以前很不爽的事情&#xff0c;现在居然能这么平静的说出来&#xff09;。 但这不是我今天说的重点&#xff0c;而是另外一件事…

【开发工具】idea配置全局变量Jdk、maven仓库、maven(全文图解)

文章目录IDEA配置JDK1、点击File -->Project Structure&#xff1b;2、点击左侧标签页SDKs选项&#xff0c;再点击左上角“”&#xff0c;选择JDK&#xff1b;3、在弹出框选择JDK安装路径&#xff0c;点击OK即可配置成功。配置maven仓库&#xff08;阿里云&#xff09;1、配…

素材要VIP咋整?看python大展神通

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 再我们缺少素材的时候&#xff0c;我们第一反应 我们肯定会去网上寻找&#xff0c;但是&#xff01;&#xff01; 有的素材需要VIP&#xff01;这可咋整呢&#xff1f; 看我利用python大展神通&#xff0c;采集某图网图片…

面试官:关于CPU你了解多少?

CPU是如何执行程序的&#xff1f; 程序执行的基本过程 第一步&#xff0c;CPU 读取「程序计数器」的值&#xff0c;这个值是指令的内存地址&#xff0c;然后 CPU 的「控制单元」操作「地址总线」指定需要访问的内存地址&#xff0c;接着通知内存设备准备数据&#xff0c;数据准…

Altium Designer(AD)软件使用记录11-PCB布线部分之走线

目录Altium Designer(AD)软件使用记录11-PCB布线部分之走线核心-SDRAM-FLASH 模块走线BGA 滤波电容放置处理其他杂线走线清理Altium Designer(AD)软件使用记录11-PCB布线部分之走线 核心-SDRAM-FLASH 模块走线 走线总结&#xff1a; 走线从核心器件部分&#xff0c;线路密度最…

Java——二叉树的最近公共祖先及二叉搜索树介绍

目录 二叉树的最近公共祖先 题目 思路一&#xff1a;如果给定的是一颗二叉搜索树&#xff0c; 思路二&#xff1a;假设是孩子双亲表示法 二叉搜索树 定义Node类 查找 删除 插入 二叉树的最近公共祖先 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百…

OpenCV入门(十一)快速学会OpenCV 10 形态学操作

OpenCV入门&#xff08;十一&#xff09;快速学会OpenCV 10 形态学操作 作者&#xff1a;Xiou 形态学&#xff0c;即数学形态学&#xff08;Mathematical Morphology&#xff09;&#xff0c;是图像处理过程中一个非常重要的研究方向。 形态学主要从图像内提取分量信息&#…

java入门多线程一文通

一、面试经典 1.为什么使用多线程及其重要 为了使用户体验更好&#xff0c;服务的相应速度更快。现如今硬件不断发展&#xff0c;软件要求也逐渐提高&#xff0c;都是为了一个字&#xff1a;快。 2.进程、线程、管程&#xff08;monitor 监视器&#xff09; 3.多线程并行和…

字符函数和字符串函数(下)——“C”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容依旧是字符函数和字符串函数呀&#xff0c;这篇博客会讲一些内存相关的函数&#xff0c;下面&#xff0c;让我们进入字符函数和字符串函数的世界吧 字符串查找 strstr strtok 错误信息报告 strerror 字符操作 内存操作函…

微信小程序搭建流程

一、申请微信开发者账号虽然开发微信小程序可以使用工具提供的测试号&#xff0c;但是测试号提供的功能极为有限&#xff0c;而且使用测试号开发的微信小程序不能上架发布。因此说我们想要开发一个可以上架的微信小程序&#xff0c;首先必须要申请微信开发者账号。大家尽可放心…

Python 四大主流 Web 编程框架

目前Python的网络编程框架已经多达几十个&#xff0c;逐个学习它们显然不现实。但这些框架在系统架构和运行环境中有很多共通之处&#xff0c;本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Python网络框架&#xff1a;Django、Tornado、Flask、Twisted。 …

Python带你制作一个属于自己的多功能音乐播放器

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 就是用Python做一个简易的音乐播放器&#xff0c;废话不多说&#xff0c;咱们直接开干 当然&#xff0c;今天做这个肯定不是最简单的&#xff0c;最简单的音乐播放器&#xff0c;9行代码足以 完整源码等直接在文末名片领…

什么是API?(详细解说)

编程资料时经常会看到API这个名词&#xff0c;网上各种高大上的解释估计放倒了一批初学者。初学者看到下面这一段话可能就有点头痛了。 API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开…

SpringCloud Alibaba 学习圣经,10万字实现 SpringCloud 自由

40岁老架构师尼恩的掏心窝&#xff1a; 现在拿到offer超级难&#xff0c;甚至连面试电话&#xff0c;一个都搞不到。 尼恩的技术社群中&#xff08;50&#xff09;&#xff0c;很多小伙伴凭借 “左手云原生右手大数据 SpringCloud Alibaba 微服务“三大绝活&#xff0c;拿到了…