K8S 启动探测、就绪探测、存活探测

先来思考一个问题:

在 Deployment 执行滚动更新 web 应用的时候,总会出现一段时间,Pod 对外提供网络访问,但是页面访问却发生404,这个问题要如何解决呢?学完今天的内容,相信你会有自己的答案。

一、理论介绍

1.1、探测类型(探针类型)

 官网介绍如下:


探测或者探针都可以,英文都是 probe:

1、启动探测 startupProbe

  • 检查容器内的应用是否已启动。
  • 如果配置了启动探测,它会禁用存活探测和就绪探测,直到启动探测成功为止。
  • 如果启动探测失败,kubelet 会将容器杀死,并依据容器重启策略进行重启
  • 如果容器没有提供启动探测,则默认状态为 Success(成功)。
  • 这类探针仅在启动时执行,不像存活探针和就绪探针那样周期性地运行。

2、就绪探测 readinessProbe

  • 决定何时容器准备好开始接受流量。
  • 如果就绪探测失败,kubelet 会将该 Pod 从所有对应服务的端点(endpoint)中移除。
  • 如果容器没有提供就绪探测,则默认状态为 Success(成功)。

3、存活探测 livenessProbe 

  • 检测容器是否正常运行。
  • 如果一个容器的存活探针失败多次,kubelet 将依据容器重启策略进行重启
  • 如果容器没有提供存活探测,则默认状态为 Success(成功)。

注意的点:

  • 启动探测 和 存活探测 都有可能重启容器。
  • 启动探测只运行一次,就绪探测跟存活探测周期性地运行着。
  • 存活探测 跟 就绪探测 是并行的。

  • 如果三个都配置,启动顺序:

  • 就绪探测 和 存活探测的区别

readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。 livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。

1.2、探测结果

1.3、检查机制(探测模式)

检查机制三种探针都一样,都有四种:

(因为三种探针都是 go 语言 Probe类型,所以它们探针类型都一样)

1、exec

  • 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。

2、grpc

  • 使用 gRPC 执行一个远程过程调用。

3、httpGet

  • 对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。

4、tcpSocket

  • 对容器的 IP 地址上的指定端口执行 TCP 检查。如果能够建立 TCP 连接,则表明容器健康。

 1.4、探针属性介绍

 探针主要属性介绍:

(因为三种探针都是 go 语言 Probe 类型,所以它们属性都一样)

kubectl explain pod.spec.containers.startupProbe

其中,exec、grpc、httpGet、tcpSocket 是检查机制,就不多说了。

1、failureThreshold

  • 连续探测失败多少次,会被认为是失败。默认值是 3,最小值为 1

2、initialDelaySeconds

  • 容器启动多少秒,探针才开始工作。

3、periodSeconds

  • 执行探测的时间间隔(单位是秒),默认为 10s,单位“秒”,最小值是1

4、successThreshold

  • 连续探测几次成功,才认为探测成功,默认为 1,在启动探针和存活探针中必须为1,最小值为1。

5、timeoutSeconds

  • 探针执行检测请求后,等待响应的超时时间,默认为1,单位“秒”。

 1.5、环境准备

假设有如下三个节点的 K8S 集群:

k8s31master 是控制节点

k8s31node1、k8s31node2 是工作节点

容器运行时是 containerd

 1.5.1、镜像准备

docker pull tomcat:8.5-jre8-alpine
docker pull busybox:1.28

  1.5.2、镜像导出

docker save -o tomcat-8.5-jre8-alpine.tar.gz docker.io/library/tomcat:8.5-jre8-alpine
docker save -o busybox-1.28.tar.gz docker.io/library/busybox:1.28

  15.3、镜像导入工作节点 containerd

# k8s31node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import tomcat-8.5-jre8-alpine.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep tomcat
[root@k8s31node1 ~]# ctr -n=k8s.io images import busybox-1.28.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep busybox# k8s31node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import tomcat-8.5-jre8-alpine.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep tomcat
[root@k8s31node2 ~]# ctr -n=k8s.io images import busybox-1.28.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep busybox

 说明:

  • ctr 是 containerd 命令
  • ctr images import:导入镜像
  • -n=k8s.io:K8S 镜像存储命名空间

三、启动探测 startupProbe

3.1、exec 模式

3.1.1、探测成功

  • pod-startupprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-exec
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:exec:command:- "/bin/sh"- "-c"- "ps -ef|grep tomcat"initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3

 initialDelaySeconds:容器启动后多久才开始探测,这里为了演示方便,故意调成 20 秒。实际业务,需要根据服务启动的平均时间来设置。假设容器启动要 10 秒,initialDelaySeconds 设置为 5 秒,太早探测,容易多次探测失败。

initialDelaySeconds 设置为 20 秒,则容易空等,不利于服务的吞吐。

periodSeconds:执行探测的时间间隔为 20 秒。

timeoutSeconds:探针执行检测请求后,等待响应的超时时间为 10 秒。

successThreshold:连续探测 1 次成功,才认为探测成功。所以如果成功,会执行 2 次探测。

failureThreshold:连续探测失败 3 次,才认为是失败。

command:要在容器里面执行的命令行。

  • /bin/sh:因为有 | 管道操作,所以需要显示地调起 shell 解释器。
  • -c:command 的意思,后接命令行字符串。
  • ps -ef|grep tomcat:打印出 tomcat 进程信息。
  • 整个命令其实是在容器中执行 /bin/sh -c "ps -ef|grep tomcat"

  • 执行并监控
kubectl apply -f pod-startupprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

运行 5s 的时候,K8S 已经确认并创建 Pod,但是这个时候,启动探测还没通过,Pod 没有一个容器 READY。20s 的时候,第一次启动探测,因为需要连续两次成功,才算成功,所以间隔 20s 又探测一次,整个 Pod 启动,用时 40s。

  •  查看 pod 事件
kubectl describe pod pod-startupprobe-exec

会发现启动探测的信息在这里。

 3.1.2、探测失败(容器重启)

  • 删除原来 pod 并修改 yaml 文件
kubectl delete -f pod-startupprobe-exec.yaml
vim pod-startupprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-exec
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:exec:command:- "false"initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3

command:

- "false" # 这一行返回非0的状态,启动探测会失败。 

  •  执行并监控
kubectl apply -f pod-startupprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

 可以看到容器在不停地重启,RESTARTS 在不停增加。

这是因为我们容器 pod.spec.containers.restartPolicy 默认为 Always。

倘若大家配置为 Never,那它就不重启了,这个大家可以试一下。 

  •   查看 pod 事件
kubectl describe pod pod-startupprobe-exec

 可以看到,K8S 会提示,启动探测失败。 

  •  删除 pod
kubectl delete -f pod-startupprobe-exec.yaml

 3.2、tcpSocket 模式

  • pod-startupprobe-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-tcpsocket
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:tcpSocket:port: 8080initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3

 tcpSocket 有两个参数:

  • host:默认 pod IP。也就是下图 10.244.165.44
  • port:必填,容器端口。

tcpSocket 类似于执行一个 telnet 10.244.165.44 8080

tomcat 也是能接收 tcp 请求的,因为 tomcat 底层用的 socket 连接。

kubectl explain pod.spec.containers.startupProbe.tcpSocket

  •  执行并监控
kubectl apply -f pod-startupprobe-tcpsocket.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

  •   删除 pod
kubectl delete -f pod-startupprobe-tcpsocket.yaml

3.3、httpGet

  • pod-startupprobe-httpget.yaml
apiVersion: v1
kind: Pod
metadata: name: pod-startupprobe-httpget
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080startupProbe:httpGet:path: /port: 8080initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 10successThreshold: 1failureThreshold: 3

 httpGet 有三个重要参数:

  • host:默认 pod IP。也就是下图 10.244.165.45
  • path:我们服务定义的路径,像 tomcat 就是根路径 /
  • port:必填,容器端口。

httpGet 类似于执行一个 curl http://10.244.165.45:8080/

kubectl explain pod.spec.containers.startupProbe.httpGet

  •  执行并监控
kubectl apply -f pod-startupprobe-httpget.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

  •   删除 pod
kubectl delete -f pod-startupprobe-httpget.yaml

四、存活探测 livenessProbe

4.1、exec 模式(容器重启)

我们来看一个 K8S 官网的例子 pod-livenessprobe-exec.yaml

apiVersion: v1
kind: Pod
metadata:name: pod-livenessprobe-exec
spec:containers:- name: livenessimage: busybox:1.28imagePullPolicy: IfNotPresentargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5

 args:容器启动的时候执行命令

  • /bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"
  • 容器启动的时候创建一个 /tmp/healthy 文件,然后睡眠 30 秒,到时间后删除文件 /tmp/healthy。接着睡眠 600 秒,防止容器退出。

command:

  •  kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。
  • 这个容器生命的前 30 秒,/tmp/healthy 文件是存在的。 所以在这最开始的 30 秒内,执行命令 cat /tmp/healthy 会返回成功代码。 30 秒之后,执行命令 cat /tmp/healthy 就会返回失败代码。
  •  执行并监控
kubectl apply -f pod-livenessprobe-exec.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

前 30 秒因为文件 /tmp/healthy 存在,存活探针探测成功。我们设置的探测间隔 periodSeconds 是 5 秒,所以在第 35 秒的时候,存活探针探测失败,又因为 failureThreshold 失败阈值我们没有设置,默认是 3,所以又要再探测 2 次,再加 10 秒,差不多 45 秒,这个时候 Pod 开始重启。

  •  在 30 秒内,查看 Pod 的事件
kubectl describe pod pod-livenessprobe-exec

 探测成功。

  • 35 秒之后,再来看 Pod 的事件
kubectl describe pod pod-livenessprobe-exec

 探测失败。45 秒的时候,容器开始重启。从这边也能看出,存活探针是周期性启动的

  • 删除 pod
kubectl delete -f pod-livenessprobe-exec.yaml

 4.2、httpGet 模式

我们来看一个官方的例子。

4.2.1、镜像拉取

由于国内无法访问 registry.k8s.io,所以我找了一个镜像中转站。

docker pull myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40

# 查看是否下载完成
docker images | grep agnhost

 4.2.2、镜像导出

docker save -o agnhost-2.40.tar.gz myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40

 4.2.3、镜像导入工作节点 containerd

# k8s31node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import agnhost-2.40.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep agnhost# k8s31node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import agnhost-2.40.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep agnhost

 4.2.4、Demo 演示

 pod-livenessprobe-httpget.yaml

apiVersion: v1
kind: Pod
metadata:name: pod-livenessprobe-http
spec:containers:- name: livenessimage: myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40imagePullPolicy: IfNotPresentargs:- livenesslivenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 2periodSeconds: 2
  • args:容器启动时设置参数 liveness。
  • initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 2 秒。
  • periodSeconds 字段指定了 kubelet 每隔 2 秒执行一次存活探测。 
  • kubelet 会向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。 如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。
  • 返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。

 容器内服务的源码:容器存活期间的最开始 10 秒钟,/healthz 处理程序返回 200 的状态码。之后处理程序返回 500 的状态码。

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {duration := time.Now().Sub(started)if duration.Seconds() > 10 {w.WriteHeader(500)w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))} else {w.WriteHeader(200)w.Write([]byte("ok"))}
})

 kubelet 在容器启动之后 2 秒开始执行健康检查。所以前几次健康检查都是成功的。 但是 10 秒之后,健康检查会失败,并且 kubelet 会杀死容器再重新启动容器。

  •   执行并监控
kubectl apply -f pod-livenessprobe-httpget.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

  •   在 10 秒内,查看 Pod 的事件
kubectl describe pod pod-livenessprobe-http

  •  10 秒之后,再来看 Pod 的事件
kubectl describe pod pod-livenessprobe-http

 存活探针已经失败,并且容器被重新启动了。

4.2.5、删除 pod

kubectl delete -f pod-livenessprobe-httpget.yaml

4.3、tcpSocket 模式

pod-livenessprobe-tcpsocket.yaml

apiVersion: v1
kind: Pod
metadata:name: pod-livenessprobe-tcp
spec:containers:- name: tomcatimage: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresentports:- containerPort: 8080livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 5
  •  执行并监控
kubectl apply -f pod-livenessprobe-tcpsocket.yaml
kubectl get pod -owide -w
# -w watch 持续监控的意思

  • 进入容器,关闭 tomcat
[root@k8s31master ~]# kubectl exec -it pod-livenessprobe-tcp -- /bin/bash
# 关闭 tomcat
bash-4.4# /usr/local/tomcat/bin/shutdown.sh

 关闭 tomcat 之后,容器状态为 Completed,然后 kubelet 检测到容器 8080 端口没有存活,重启容器。

  • 删除 pod
kubectl delete -f pod-livenessprobe-tcpsocket.yaml

    五、就绪探测 readinessProbe

    5.1、exec 模式(容器不会重启)

    pod-readinessprobe-exec.yaml

    apiVersion: v1
    kind: Pod
    metadata:name: pod-readinessprobe-exec
    spec:containers:- name: readinessimage: busybox:1.28imagePullPolicy: IfNotPresentargs:- /bin/sh- -c- sleep 20; touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600readinessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5

    args:容器启动的时候执行命令

    • /bin/sh -c "sleep 20; touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600"
    • 容器启动的时候先睡眠 20 秒,到时间后创建一个 /tmp/healthy 文件,然后睡眠 10 秒,到时间后删除文件 /tmp/healthy。接着睡眠 600 秒,防止容器退出。

    command:

    •  kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是就绪的,可以对外提供服务。 如果这个命令返回非 0 值,kubelet 会隔 5 秒重新探测。
    • 这个容器生命的前 20 秒,/tmp/healthy 文件是不存在的。所以在这最开始的 20 秒内,执行命令 cat /tmp/healthy 会返回失败代码,容器 READY 个数为 0 。20 秒之后,执行命令 cat /tmp/healthy 就会返回成功代码,这个时候容器 READY 个数就会变为 1。再过了 10 秒,/tmp/healthy文件被删除,就绪探测失败,容器 READY 个数重新变为 0,然后隔 5 秒重新探测一次。在整个过程中,容器不会重启
    •  执行并监控
    kubectl apply -f pod-readinessprobe-exec.yaml
    kubectl get pod -owide -w
    # -w watch 持续监控的意思

     因为 readinessProbe 不会重启,所以经常要跟 livenessProbe 搭配使用。

    •   在 20 秒内,查看 Pod 的事件
    kubectl describe pod pod-readinessprobe-exec

    • 20 秒到 30 秒,查看 Pod 的事件
    kubectl describe pod pod-readinessprobe-exec

    • 30 秒以后,查看 Pod 的事件
    kubectl describe pod pod-readinessprobe-exec

    实际的 Age 时间与我们预期的会有一些出入。不过监控 -w 里面的时间,跟我们分析的是吻合的。

    •  删除 pod
    kubectl apply -f pod-readinessprobe-exec.yaml

     5.2、httpGet 模式

    pod-readinessprobe-http.yaml

    apiVersion: v1
    kind: Pod
    metadata:name: pod-readinessprobe-http
    spec:containers:- name: readinessimage: myifeng/registry.k8s.io_e2e-test-images_agnhost:2.40imagePullPolicy: IfNotPresentargs:- livenessreadinessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 5periodSeconds: 3
    •  执行并监控 
    kubectl apply -f pod-readinessprobe-http.yaml
    kubectl get pod -owide -w
    # -w watch 持续监控的意思

    就绪探测 5 秒之后开始,容器存活期间的最开始 10 秒钟,/healthz 处理程序返回 200 的状态码,容器 READY 变为 1/1。之后容器内处理程序返回 500 的状态码,容器 READY 变为 0/1,之后每隔 3 秒重新探测一次。

    • 删除 pod
    kubectl delete -f pod-readinessprobe-http.yaml

     六、开头问题解答

    在 Deployment 执行滚动更新的时候,总会出现一段时间,Pod 对外提供网络访问,但是访问却发生404,这个问题要如何解决呢?

    问题的原因,是因为 Pod 已经成功启动,但是 Pod 内的容器中应用程序还在启动中导致。

    可以使用就绪探针,去检测系统中,页面元素适中、接口响应时间在平均时间的页面或接口,使用 httpGet 模式去探测它,成功了才加到系统 EndPoint 中。

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

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    开源 CSS 框架 Tailwind CSS v4.0

    开源 CSS 框架 Tailwind CSS v4.0 于 1 月 22 日正式发布,除了显著提升性能、简化配置体验外,还增强了功能特性,具体如下1: 性能提升 采用全新的高性能引擎 Oxide,带来了构建速度的巨大飞跃: 全量构建速度…

    YOLOv10 介绍

    YOLOv10 是清华大学多媒体智能组推出的新一代目标检测算法。以下是它的一些主要信息: 主要特点与优势: 实时性与准确性并重:在保持高准确性的同时,实现了毫秒级的实时检测速度。通过引入大核卷积和部分自注意模块,在较低计算成本下实现了更高的性能。优化的模型架构: 主干…

    基于物联网的智能环境监测系统(论文+源码)

    1系统的功能及方案设计 本课题为基于物联网的智能环境监测系统的设计与实现,整个系统采用stm32f103单片机作为主控制器,通过DHT11传感器实现智能环境监测系统温度和湿度的检测,通过MQ传感器实现CO2浓度检测,通过光照传感器实现光照…

    过年之无用知识研究:std::is_assignable means?

    std::pair的默认operator被delete掉了,取而代之的是两个enable_if版本。 为什么这么设计,我的理解是pair作为左值时,里面的first如果是const,那么就不允许了。比如,在std::map里,已经保存的元素的key值是不…

    978.最长湍流子数组

    目录 题目过程解法收获 题目 给定一个整数数组 arr ,返回 arr 的 最大湍流子数组的长度 。 如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是 湍流子数组 。 更正式地来说,当 arr 的子数组 A[i], A[i1], …, A[j] 满足仅满足…

    【愚公系列】《循序渐进Vue.js 3.x前端开发实践》030-自定义组件的插槽Mixin

    标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主&…

    学习第七十六行

    提高github下载速度方法 1.github转码云 2.https://github.com.cnpmjs.org com后面加东西 对于面试笔试,最好方法刷力扣,1000题包进大厂的

    leetcode刷题-贪心03

    代码随想录贪心算法part03|134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列 134. 加油站【太牛了】135. 分发糖果860.柠檬水找零406.根据身高重建队列 134. 加油站【太牛了】 leetcode题目链接 代码随想录文档讲解 思路: 两个数组: …

    基于SpringBoot电脑组装系统平台系统功能实现六

    一、前言介绍: 1.1 项目摘要 随着科技的进步,计算机硬件技术日新月异,包括处理器(CPU)、主板、内存、显卡等关键部件的性能不断提升,为电脑组装提供了更多的选择和可能性。不同的硬件组合可以构建出不同类…

    【某大厂一面】数组和链表区别

    在 Java 中,数组(Array)和链表(LinkedList)是两种常见的数据结构,它们在存储和操作方式上有显著的区别。了解它们的差异有助于选择适合特定应用场景的结构。下面是数组和链表之间的详细比较。 1. 存储结构…

    网络工程师 (5)系统可靠性

    前言 系统可靠性是指系统在规定的条件和规定的时间内,完成规定功能的能力。这种能力不仅涵盖了系统本身的稳定性和耐久性,还涉及了系统在面对各种内外部干扰和故障时的恢复能力和容错性。系统可靠性是评价一个系统性能优劣的关键指标之一,对于…

    【2024年华为OD机试】(C卷,200分)- 推荐多样性 (JavaScriptJava PythonC/C++)

    一、问题描述 问题描述 我们需要从多个已排序的列表中选取元素,以填充多个窗口。每个窗口需要展示一定数量的元素,且元素的选择需要遵循特定的穿插策略。具体来说,我们需要: 从第一个列表中为每个窗口选择一个元素,…

    C# 提取PDF表单数据

    目录 使用工具 C# 提取多个PDF表单域的数据 C# 提取特定PDF表单域的数据 PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景。凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用。然而,当需要整合…

    http://noi.openjudge.cn/——4.2算法之数论——2419:Coins

    题目 总时间限制: 1000ms 内存限制: 131072kB 描述 Snoopy has three coins. One day he tossed them on a table then and tried to flip some of them so that they had either all heads or all tails facing up. After several attempts, he found that regardless of the…

    损失函数 Loss Function

    分类问题和回归问题常使用的损失函数如下: 分类问题 交叉熵损失函数(Cross-Entropy Loss):用于衡量两个概率分布之间的差异,在多分类问题中广泛应用。 ce_loss nn.CrossEntropyLoss() 回归问题 均方误差损失函数&…

    3.日常英语笔记

    screening discrepancies 筛选差异 The team found some screening discrepancies in the data. 团队在数据筛选中发现了些差异。 Don’t tug at it ,or it will fall over and crush you. tug 拉,拽,拖 He tugged the door open with all his might…

    解析“in the wild”——编程和生活中的俚语妙用

    解析“in the wild”——编程和生活中的俚语妙用 看下面的技术文章中遇到 in the wild这个词,想要研究一下,遂产生此文。 Are there ever pointers to pointers to pointers? There is an old programming joke which says you can rate C programmers…

    软件测试丨从自动化软件测试到自主测试,还差几步?

    在当今万物互联、信息爆炸的时代,软件测试的角色显得越发重要。作为软件开发生命周期(SDLC)中的关键环节,测试不仅仅是保障软件质量的工具,更是推动产品迭代的助推器。随着自动化测试技术的崛起,测试开发变…

    高阶C语言|深入理解字符串函数和内存函数

    文章目录 前言1.求字符串长度1.1 字符串长度函数:strlen模拟实现 长度不受限制的字符串函数1.2 字符串拷贝函数:strcpy模拟实现 1.3 字符串连接函数:strcat模拟实现 1.4 字符串比较函数:strcmp模拟实现 长度受限制的字符串函数2.1…

    Golang Ticker Reset异常的坑

    前言 延迟执行的场景我们通常会使用time.NewTimer(…)来实现,当一些场合可能需要使用timer.Reset(…)方法修改超时时间,这时使用要多注意, 使用不当会导致Reset失败,或是重复执行两次的情况。 复现 下面这段代码我们是希望&…