我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何解决K8s中快速交付应用的难题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何解决K8s中快速交付应用的难题

如何解决K8s中快速交付应用的难题,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

前言

软件技术更新换代很快,但我们追求的目标是一直不变的,那就是在安全稳定的前提下,增加应用的部署频率,缩短产品功能的迭代周期,这样的好处就是企业可以在更短的时间内获得产品的价值、更快地获得客户反馈和响应客户需求,从而进一步提升产品的竞争力;除此之外,企业还可以释放更多的资源投入到创新业务的研发上,创造更多的价值,这是一个良性循环的过程。

应用产品的快速迭代诚然能给我们带来各种各样的好处,但挑战也与其并存。更高频率的应用发布,意味着线上业务有不可预期故障的风险更大,除了产品上线之前在预发测试环境中充分测试验证迭代功能之外,制定最合适的应用发布策略就是另外一个非常重要的话题,因为它可以最大限度的降低业务故障的风险以及带来的损失。

云原生应用交付的关键点

我们说频繁地进行产品迭代意味着更大的故障风险,传统应用如此,云原生应用更是如此。因为云原生应用通常都是基于云的分布式部署模式,且每个应用可能是由多个功能组件互相调用来一起提供完整的服务的,每个组件都有自己独立的迭代流程和计划。在这种情况下,功能组件越多,意味着出错的概率越大。那么如何在应用交付层面对上述这些痛点做出改进,我们总结出以下几个云原生应用交付的关键点。

如何解决K8s中快速交付应用的难题

  • 如何充分利用云原生架构基础设施的优势。这个优势我们可以简单总结为两点:弹性和高可用;

  • 如何具有跨平台移植和交付的能力。基础设施底层的计算、存储、网络资源有很大的差异化,在以前,基础架构的不同是由上层应用决定的,而云原生应用的交付需要具有跨平台移植和交付的能力;

  • 如何实现应用运维自治化。自治化不等于自动化,自动化是指触发一个流程,流程结束后能自动达到想要的一个预期结果,而自治化是指应用再高可用的运行态时,如果其中某个功能组件的某个副本出现故障,应用能自动移除故障副本并补充新的应用副本;

  • 如何让应用变得更具有可预测性。应用的交付终态,在我们编写应用编排模板的时候就是可预测到的,如果应用的交付变得更有可预测性,那么风险也会最大程度地降低;

  • 如何提高应用更快的平均恢复时间。如果应用有超出了应用自治的能力范畴之外的故障发生需要人工介入,那更快的平均恢复时间就意味着更低的业务损失。

Kubernetes 是一个可移植的,可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。它自身的平台能力已经满足了我们前面提到的大部分需求。Kubernetes 使用容器技术部署应用,这样的好处包括但不限于:

  • 应用程序创建和部署更敏捷

  • 可移植性

  • 环境一致性

  • 松耦合和分布式

  • 资源隔离

  • 高效率和高密度的资源利用

如何解决K8s中快速交付应用的难题

Kubernetes 还提供了应用管理、调度、监控和运维的强大能力:

  • 服务发现和负载均衡能力

  • 应用的自动部署和回滚能力

  • 应用的自治修复能力

  • 存储编排能力

  • 密钥和配置管理能力

但 Kubernetes 它也有很多功能是不提供但允许扩展的部分,比如日志采集、监控报警等能力。下面这张图就是阿里云容器服务是在支持标准 Kubernetes 的基础上,对与用户息息相关的能力做了增强和提升后的架构大图,包括提供最大的弹性化与低廉成本的全球化接入能力,强大的安全架构支撑能力,深度整合阿里云基础资源服务的能力,并经过 双11 验证和沉淀了海量用户经验,同时支持专有、托管、无服务化、边缘和神龙裸金属等多种产品形态,我们今天后面的所有演示就是在此平台上做的。

如何解决K8s中快速交付应用的难题

应用交付的边界

在 Kubernetes 中应用交付的边界是什么?

从简单处入手,我们可以认为应用的交付就是它的网络服务模式,服务的的后端资源以及业务数据的持久化存储,这些资源被分别抽象成 service、deployment/pod,volume 资源等。

如何解决K8s中快速交付应用的难题

以一个 wordpress 应用为例,它包括两个功能组件:前端组件处理用户请求,后端组件存储数据。前端组件包括一个 frontend service 和 3 个 pod,后端组件包括一个 backend service 和一个 pod 组件,所以这个 wordpress 应用交付的资源就是 2 个 service 和总共 4 个后端 pod。这个后端的 pod 资源我们在 Kubernetes 中通过 deployment 来统一管理,service 资源相当于一个负载均衡器,把请求路由到后端 pod 上,它涉及集群内各个组件之间调用以及外部用户访问集群内服务,所以有不同的种类划分。

如何解决K8s中快速交付应用的难题

根据服务暴露的方式不同,可以分为以下几种:

ClusterIP

通过为 Kubernetes 的 Service 分配一个集群内部可访问的固定虚拟 IP(Cluster IP),实现集群内的访问。为最常见的方式。

apiVersion: v1kind: Servicemetadata:  name: wordpressspec:  type: ClusterIP      # 默认的service类型,服务仅暴露为集群内部可访问  ports:    - port: 80         # 暴露给集群内部的服务端口      targetPort: 80   # 容器监听的服务端口      protocol: TCP  selector:    app: wordpress     # 转发请求到有相同标签的后端pod

NodePort

NodePort 是把 service 的 port 映射到集群节点的一个端口上,如果你不指定这个端口,系统将选择一个随机端口。大多数时候我们应该让 Kubernetes 来选择端口,用户自己来选择可用端口代价太大。

apiVersion: v1kind: Servicemetadata:  name: wordpressspec:  type: NodePort       # NodePort service类型,服务暴露一个固定的静态端口用于集群外部访问  ports:    - port: 80         # 暴露给集群内部的服务端口      targetPort: 80   # 容器监听的服务端口      protocol: TCP      nodePort: 31570  # 集群外部可以通过此端口访问服务  selector:    app: wordpress     # 转发请求到有相同标签的后端pod

NodePort 的方式虽然可以把服务暴露给集群外访问,但是也有很多缺点:

  • 每个端口只能是一种服务

  • 端口范围有限制,一般是 30000-32767

  • 如果节点的 IP 地址变化了的话,你需要做一些变更操作去适配

所以在生产中一般不推荐这种方式,但如果你的应用对成本比较敏感又能容忍服务有不可用窗口期的话,是可以使用这种方式的。

如何解决K8s中快速交付应用的难题

LoadBalancer

LoadBalancer 是服务暴露到集群外或者公网上的标准方式,但它依赖 cloud provider 提供的一个负载均衡器的能力,负载均衡器会单独分配一个 ip 地址并监听后端服务的指定端口,请求的流量会通过指定的端口转发到后端对应的服务。

apiVersion: v1kind: Servicemetadata:  name: wordpressspec:  type: LoadBalancer       # LoadBalancer service类型,一般依赖于公共云厂商供的负载均衡能力  ports:    - port: 80         # 暴露给集群内部的服务端口      targetPort: 80   # 容器监听的服务端口      protocol: TCP  selector:    app: wordpress     # 转发请求到有相同标签的后端pod

如何解决K8s中快速交付应用的难题

Ingress

ClusterIP 服务类型仅限集群内通信,NodePort 可以实现暴露服务访问入口,但每个节点都会占用一个端口,会增加端口管理的复杂性,LoadBalancer 通常需要第三方云提供商支持,有一定的约束性。而 Ingress 这个服务类型跟我们前面的三种服务类型不一样,它实际上不是一种服务类型,而是类似一种集群服务入口的存在,它可以基于你配置的不同路径或者子域名把流量路由到对应的后端服务,更像是一个“智能路由”服务。

如何解决K8s中快速交付应用的难题

前面介绍了一些应用发布涉及到的资源类型,以及 service 资源类型的几种模式,那 service 如何找到对应的后端 pod 呢,这个就是标签的作用,我们可以把每个应用的 pod 和 service 都打上同样的标签,这个标签的机制就是我们后面要讲的几种应用发布策略的关键点了。

如何解决K8s中快速交付应用的难题

应用的发布策略

在 Kubernetes 集群中,除了根据业务需求选定服务暴露方式外,为了让应用在升级期间依然平稳提供服务,选择一个正确的发布策略就非常重要了。

滚动发布

第一种应用发布策略就是滚动发布,这也是比较常见的策略。它是通过逐个替换实例来逐步部署新版本的应用,直到所有实例都被替换完成为止。

如下图所示,当前我的应用提供的服务版本是 v1, 这个服务的后端有 3 个副本, 但我更新版本 v2 的时候,它是一个副本一个副本地开始替换,直到最终服务的后端全部替换成 v2 版本。

如何解决K8s中快速交付应用的难题

一个应用示例的编排文件如下所示:

  • go-demo-v1.yaml

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demospec:  replicas: 3  selector:    matchLabels:      app: go-demo  template:    metadata:      labels:        app: go-demo    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v1        imagePullPolicy: Always        ports:        - containerPort: 8080---apiVersion: v1kind: Servicemetadata:  name: go-demospec:  ports:  - port: 80    targetPort: 8080    name: go-demo  selector:    app: go-demo  type: ClusterIP
  • 部署版本 v1

$ kubectl apply -f go-demo-v1.yaml
  • 查看 pod 运行状态

$ kubectl get poNAME                       READY   STATUS    RESTARTS   AGEgo-demo-78bc65c564-2rhxp   1/1     Running   0          19sgo-demo-78bc65c564-574z6   1/1     Running   0          19sgo-demo-78bc65c564-sgl2s   1/1     Running   0          19s
  • 访问应用服务

$ while sleep 0.1; do curl http://172.19.15.25; doneVersion: v1Version: v1Version: v1Version: v1Version: v1Version: v1
  • 更新 go-demo-v1.yamlgo-demo-v2.yaml 并更新镜像 tag

...registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v2...
  • 部署版本 v2

$ kubectl apply -f go-demo-v2.yaml
  • 可以查看 pod 会被新版本 pod 逐个替换

$kubectl get po -wNAME                                READY   STATUS              RESTARTS   AGEapplication-demo-8594ff4967-85jsg   1/1     Running             0          3m24sapplication-demo-8594ff4967-d4sv8   1/1     Terminating         0          3m22sapplication-demo-8594ff4967-w6lpz   0/1     Terminating         0          3m20sapplication-demo-b98d94554-4mwqd    1/1     Running             0          3sapplication-demo-b98d94554-ng9wx    0/1     ContainerCreating   0          1sapplication-demo-b98d94554-pmc5g    1/1     Running             0          4s
  • 访问服务会发现在应用滚动升级过程中,版本 v1 和 v2 都会被访问到,这个时间的长短取决于应用的启动速度

$ while sleep 0.1; do curl http://172.19.15.25; doneVersion: v1Version: v2Version: v1Version: v1Version: v2Version: v1Version: v1Version: v2

滚动发布优点就是它比较简单,而且不会占用太多的计算资源。缺点是:

  • 版本在实例之间缓慢替换

  • 这个滚动发布可能需要一定时间

  • 无法控制流量

从应用在集群中的终态上来说,集群中要么只有版本 1 的应用后端,要么只有版本 2 的后端;如果版本 2 有缺陷,那么线上服务应用到的就是整体用户, 虽然我们有机制可以快速回滚,但涉及到整体用户使用故障的代价还是太大。

蓝绿发布

第二种就是蓝绿发布,蓝/绿发布是应用版本 1 与版本 2 的后端 pod 都部署在环境中,通过控制流量切换来决定发布哪个版本。与滚动发布相比,蓝绿发布策略下的应用终态,是可以同时存在版本 1 和版本 2 两种 pod 的,我们可以通过 service 流量的切换来决定当前服务使用哪个版本的后端。

如何解决K8s中快速交付应用的难题

一个应用示例的编排文件如下所示。

  • go-demo-v1.yaml

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demo-v1spec:  replicas: 4  selector:    matchLabels:      app: go-demo      version: v1  template:    metadata:      labels:        app: go-demo        version: v1    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v1        imagePullPolicy: Always        ports:        - containerPort: 8080
  • go-demo-v2.yaml

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demo-v2spec:  replicas: 4  selector:    matchLabels:      app: go-demo      version: v2  template:    metadata:      labels:        app: go-demo        version: v2    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v2        imagePullPolicy: Always        ports:        - containerPort: 8080
  • service.yaml

apiVersion: v1kind: Servicemetadata:  name: go-demospec:  ports:  - port: 80    targetPort: 8080    name: go-demo  selector:    app: go-demo    version: v1  type: ClusterIP
  • 部署以上 3 个资源

$ kubectl apply -f go-demo-v1.yaml -f go-demo-v2.yaml -f service.yaml
  • 访问服务可以看到目前只访问到版本 1 的服务

$ while sleep 0.1; do curl http://172.19.8.137; doneVersion: v1Version: v1Version: v1Version: v1Version: v1
  • 修改 service.yaml 的 spec.selector 下 version=v2

apiVersion: v1kind: Servicemetadata:  name: go-demospec:  ports:  - port: 80    targetPort: 8080    name: go-demo  selector:    app: go-demo    version: v2  type: ClusterIP
  • 重新部署

$ kubectl apply -f service.yaml
  • 重新访问服务可以看到很快切换到了版本 2 上

$ [root@iZbp13u3z7d2tqx0cs6ovqZ blue-green]# while sleep 0.1; do curl http://172.19.8.137; doneVersion: v2Version: v2Version: v2

我们刚才说到滚动升级有一个过程需要时间,即使回滚,它也需要一定的时间才能回滚完毕,在新版本应用有缺陷的情况下,蓝绿发布的策略可以快速在 v1 和 v2 两个版本之前切流量,所以这个切换流量的时间跟滚动升级相比就缩短了很多了,但蓝绿发布的缺点跟滚动发布相同的就是这个缺陷会影响到整体用户,服务要么百分百切换到版本 2 上,要么百分百切换到版本 1 上,这是个非 0 即 100 的操作,即使蓝绿发布策略可以大大缩短故障恢复时间,但在某些场景下也是不可接受的。 而且集群环境中同时存在两个版本的 pod 副本,资源占用的话相比滚动发布是 2 倍的。

金丝雀发布(灰度发布)

第三种要介绍的发布策略是金丝雀发布,金丝雀部署是应用版本 1 和版本 2 同时部署在环境中,并且用户请求有可能会路由到版本 1 的后端,也可能会路由到版本 2 的后端,从而达到让一部分新用户访问到版本 2 的应用。 这种发布策略下,我们可以通过调整流量百分比来逐步控制应用向新的版本切换,它与蓝绿部署相比,不仅继承了蓝绿部署的优点,而且占用资源优于蓝绿部署所需要的 2 倍资源,在新版本有缺陷的情况下只影响少部分用户,把损失降到最低。

如何解决K8s中快速交付应用的难题

对于灰度发布的概念来说,有人认为它跟金丝雀发布讲的是一个东西,有人认为它们不同。它跟金丝雀发布的过程是相同的,但目的有所不同:

  • 金丝雀发布更倾向于能快速获取用户的一些反馈,比如我可能不确定我的这个新版本功能的用户体验是否能被大众很好的接受,我期望能得到线上用户的一些及时反馈,在产品侧做功能体验调整之后再迭代 v3 版本;

  • 而灰度发布则是我的产品功能已经设计并开发的很完善了,现在就是要逐步替换线上的旧版本,但是要控制发布可能带来的风险,所以要灰度发布。

示例应用 1 如下, 这个示例中我们通过 pod 的数量来控制流量比例。

  • go-demo-v1.yaml 设定副本数为 9

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demo-v1spec:  replicas: 9  selector:    matchLabels:      app: go-demo      version: v1  template:    metadata:      labels:        app: go-demo        version: v1    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v1        imagePullPolicy: Always        ports:        - containerPort: 8080
  • go-demo-v2.yaml 设定副本数为 1

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demo-v2spec:  replicas: 1  selector:    matchLabels:      app: go-demo      version: v2  template:    metadata:      labels:        app: go-demo        version: v2    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v2        imagePullPolicy: Always        ports:        - containerPort: 8080
  • service.yaml

apiVersion: v1kind: Servicemetadata:  name: go-demospec:  ports:  - port: 80    targetPort: 8080    name: go-demo  selector:    app: go-demo  type: ClusterIP
  • 部署以上 3 个资源

$ kubectl apply -f go-demo-v1.yaml -f go-demo-v2.yaml -f service.yaml
  • 访问服务可以看到基本上是 10% 的流量切换到版本 2 上

$ while sleep 0.1; do curl http://172.19.8.248; doneVersion: v1Version: v2Version: v1Version: v1Version: v1Version: v1Version: v1Version: v1Version: v1Version: v1Version: v1

另外我们可以使用 nginx ingress controller 来控制流量切换,这个方式要更精准。

  • go-demo-v1.yaml

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demo-v1spec:  replicas: 3  selector:    matchLabels:      app: go-demo      version: v1  template:    metadata:      labels:        app: go-demo        version: v1    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v1        imagePullPolicy: Always        ports:        - containerPort: 8080
  • go-demo-v2.yaml

apiVersion: apps/v1kind: Deploymentmetadata:  name: go-demo-v2spec:  replicas: 1  selector:    matchLabels:      app: go-demo      version: v2  template:    metadata:      labels:        app: go-demo        version: v2    spec:      containers:      - name: go-demo        image: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/go-demo:v2        imagePullPolicy: Always        ports:        - containerPort: 8080
  • service-v1.yaml

apiVersion: v1kind: Servicemetadata:  name: go-demo-v1spec:  ports:  - port: 80    targetPort: 8080    name: go-demo  selector:    app: go-demo    version: v1  type: ClusterIP
  • service-v2.yaml

apiVersion: v1kind: Servicemetadata:  name: go-demo-v2spec:  ports:  - port: 80    targetPort: 8080    name: go-demo  selector:    app: go-demo    version: v2  type: ClusterIP
  • ingress.yaml, 设置 nginx.ingress.kubernetes.io/service-weight: | go-demo-v1: 100, go-demo-v2: 0, 版本1 - 100% 流量, 版本2 - 0% 流量

apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    nginx.ingress.kubernetes.io/service-weight: |        go-demo-v1: 100, go-demo-v2: 0  name: go-demo  labels:    app: go-demospec:  rules:    - host: go-demo.example.com      http:        paths:          - path: /            backend:              serviceName: go-demo-v1              servicePort: 80          - path: /            backend:              serviceName: go-demo-v2              servicePort: 80
  • 部署以上 4 个资源

$ kubectl apply -f go-demo-v1.yaml -f go-demo-v2.yaml -f service-v1.yaml -f service-v2.yaml -f nginx.yaml
  • 访问服务可以看到流量 100% 到版本 1 上

$ while sleep 0.1; do curl http://go-demo.example.com; doneVersion: v1Version: v1Version: v1Version: v1Version: v1Version: v1
  • 更新 ingress.yaml, 设置流量比为 50:50

apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    nginx.ingress.kubernetes.io/service-weight: |        go-demo-v1: 50, go-demo-v2: 50  name: go-demo  labels:    app: go-demospec:  rules:    - host: go-demo.example.com      http:        paths:          - path: /            backend:              serviceName: go-demo-v1              servicePort: 80          - path: /            backend:              serviceName: go-demo-v2              servicePort: 80
  • 访问服务可以看到流量 50% 到版本 1 上, 50% 到版本 2 上

$ while sleep 0.1; do curl http://go-demo.example.com; doneVersion: v2Version: v1Version: v1Version: v1Version: v2Version: v2Version: v1Version: v1Version: v2Version: v2
  • 更新 ingress.yaml, 设置流量比为 0:100

apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    nginx.ingress.kubernetes.io/service-weight: |        go-demo-v1: 0, go-demo-v2: 100  name: go-demo  labels:    app: go-demospec:  rules:    - host: go-demo.example.com      http:        paths:          - path: /            backend:              serviceName: go-demo-v1              servicePort: 80          - path: /            backend:              serviceName: go-demo-v2              servicePort: 80
  • 访问服务可以看到流量 100% 到版本 2 上

$ while sleep 0.1; do curl http://go-demo.example.com; doneVersion: v2Version: v2Version: v2Version: v2Version: v2Version: v2Version: v2Version: v2Version: v2Version: v2

不管是金丝雀发布还是灰度发布,缺点就是发布周期相对来说要慢很多。

在这些发布策略当中,

  • 当你在开发测试环境中对应用做更新发布的话,用滚动发布;

  • 在生产环境,滚动更新或者蓝绿发布在新版本已经提前测试充分的情况下可以用;

  • 如果对新版本的应用的更新需要最大限度地控制风险,降低故障对用户的影响的话,那就使用金丝雀发布或灰度发布。

以上就是我们在 Kubernetes 当中常用的几种发布策略的介绍。

关于如何解决K8s中快速交付应用的难题问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何解决K8s中快速交付应用的难题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何解决K8s中快速交付应用的难题

如何解决K8s中快速交付应用的难题,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。前言软件技术更新换代很快,但我们追求的目标是一直不变的,那就是在安全稳定的前提下,增加应用的
2023-06-04

如何快速解决网站开发中的排名问题

如何快速解决网站开发中的排名问题,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。网站参与搜索引擎排名是每个SEOer都想要达到的目标,然而说起来简单的问题,做起来其实并没有想
2023-06-12

如何在java中使用分治法中的快速排序解决排序问题

问题描述:输入一个数字N后,输入N个数字,将N个数字排序后输出。输入:输出:算法设计:快速排序的基本思想是基于分治策略的,其算法思想如下:(1)分解:先从数列中取出一个元素作为基准元素.以基准元素为标准,将问题分解为两个子序列,使小于或等于基准元素的子序列在左
如何在java中使用分治法中的快速排序解决排序问题
2021-12-23

如何使用Win7自带的“问题步骤记录器”快速解决系统问题

当我们在使用电脑的过程中遇到问题时,首先可能会去百度一下,或者通过电话、QQ求助别人。但是有时遇到的问题并不能用语言很好的表达出来,最后造成自己说不明白,对方也听不明白的情况,问题没解决不说,还白白耽误了时间。如果能将遇到问题的操作录下来,
2023-06-01

Helm如何解决Kubernetes中部署应用的问题

这篇文章将为大家详细讲解有关Helm如何解决Kubernetes中部署应用的问题,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、背景Kubernetes(k8s)是一个基于容器技术的分布式
2023-06-04

如何解决Dreamweaver中关于应用CSS的小问题

这篇文章主要介绍了如何解决Dreamweaver中关于应用CSS的小问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  Dreamweaver是集网页制作和管理网站于一身的
2023-06-08

如何解决Win10系统中应用商店不见的问题

小编给大家分享一下如何解决Win10系统中应用商店不见的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!方法/步骤:1.按住键盘上的“win”+“X”按键调出以
2023-06-27

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录