【云原生】k8s之包管理器Helm

前言

 每个成功的软件平台都有一个优秀的打包系统,比如Debian、Ubuntu 的 apt,RedHat、CentOS 的 yum。Helm 则是 Kubernetes上 的包管理器,方便我们更好的管理应用。

1.Helm的相关知识 

1.1 Helm的简介与了解 

 Helm本质就是让K8s的应用管理(Deployment、Service等)可配置,可以通过类似于传递环境变量的方式能动态生成。通过动态生成K8s资源清单文件(deployment.yaml、service.yaml)。 然后调用 Kubectl 自动执行 K8s 资源部署。

在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。 况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm 通过打包的方式,支持发布的版本管理和控制, 很大程度上简化了 Kubernetes 应用的部署和管理。
 Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。

Helm的官网地址:http:// https://helm.sh/

1.2 Helm的三个重要概念


在Helm中 有三个重要的概念,分别为:Chart 、Repository 和 Release 

●Chart:Helm 的软件包,采用 TAR 格式。是创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说明等。chart 是应用部署的自包含逻辑单元。 可以将 chart 想象成 apt、yum 中的软件安装包。

●Release:是 chart 的运行实例,代表了一个正在运行的应用。当 chart 被安装到 Kubernetes 集群,就生成一个 release。chart 能够多次安装到同一个集群,每次安装都是一个 release。

●Repository(仓库):Charts 仓库,用于集中存储和分发 Charts。Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。

还有一个在Helm3版本中就被移除的概念:

Tiller: Helm 2.x版本中,Helm采用Client/Server的设计,Tiller就是Helm的Server部分,需要具备集群管理员权限才能安装到K8s集群中运行。Tiller与Helm client进行交互,接收client的请求,再与K8s API Server通信,根据传递的Charts来生成Release。而在最新的Helm 3.x中,据说是为了安全性考虑移除了Tiller。 

Helm在k8s集群运用中,总的来讲其作用过程:Helm 安装 charts 到 Kubernetes 集群中,每次安装都会创建一个新的 release。你可以在 Helm 的 chart repositories 中寻找新的 chart。 
 

 

2.Helm在k8s集群中的部署

(1)将Helm安装在master01节点上 

//在github中下载所需版本的二进制 Helm client 安装包
https://github.com/helm/helm/tags 
 
tar -zxvf helm-v3.6.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
helm version
 

 添加helm的自动补全功能,方便后续使用:

vim /etc/bashrc
source <(helm completion bash)

(2)使用 helm 安装 Chart 

###helm添加chat的语法格式:
helm repo add  chart仓库名   chart仓库地址
 
###添加常用的chart仓库############
#一个开源项目的仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
#微软chart仓库,推荐使用,内容基本与官方仓库保持一致
helm repo add stable http://mirror.azure.cn/kubernetes/charts
#阿里chart仓库,应有尽有
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
#官方仓库,国内网络问题,不太推荐应用
helm repo add incubator https://charts.helm.sh/incubator

 

(3)对chart仓库的基本使用 

1)更新和查看 charts 列表

helm repo update          
helm repo list
 

 

2)查看某chart仓库的可用chart列表 

//查看 stable 仓库可用的 charts 列表
helm search repo stable
 

 3)删除指定的chart仓库

//eg:因为官方仓库使用起来太慢,删除 incubator 仓库
helm repo remove incubator
 

 

 4)查看 chart 信息

 
helm show chart stable/mysql     #查看指定 chart 的基本信息

helm show all stable/mysql         #获取指定 chart 的所有信息

(4)安装 chart 

helm install my-redis bitnami/redis [-n default]   #指定 release 的名字为 my-redis,-n 指定部署到 k8s 的 namespace
 
helm install bitnami/redis --generate-name    #不指定 release 的名字时,需使用 –generate-name 随机生成一个名字

 

(5)对chart的基本管理

 1)查看所有的release

helm ls 
helm list

 

2)查看指定的 release 状态

helm status my-redis 

 

 3)删除指定的release

helm uninstall my-redis 
 

  3.Helm的自定义模板

 charts 除了可以在 repo 中下载,还可以自己自定义,创建完成后通过 helm 部署到 k8s。

3.1 在镜像仓库中拉取chart,查看chart的包结构

#拉取chart 到本地目录(现在所在的目录中)
helm pull stable/mysql
 
#对该拉取的chart压缩包进行解压
tar xf mysql-1.6.9.tgz

 

 

 由上图可以看出:一个 chart 包就是一个文件夹的集合,文件夹名称就是 chart 包的名称。

 chart 是包含至少两项内容的helm软件包:

(1)软件包自描述文件 Chart.yaml,这个文件必须有 name 和 version(chart版本) 的定义
(2)一个或多个模板,其中包含 Kubernetes 清单文件:

NOTES.txt:chart 的“帮助文本”,在用户运行 helm install 时显示给用户
deployment.yaml:创建 deployment 的资源清单文件
service.yaml:为 deployment 创建 service 的资源清单文件
ingress.yaml: 创建 ingress 对象的资源清单文件
_helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用

 

3.2 自定义创建一个chart 

(1)使用命令行创建生成一个模板

helm create nginx
 
tree nginx

 

cat nginx/templates/deployment.yaml

 

 在 templates 目录下 yaml 文件模板中的变量(go template语法)的值默认是在 nginx/values.yaml 中定义的,只需要修改 nginx/values.yaml 的内容,也就完成了 templates 目录下 yaml 文件的配置。
比如在 deployment.yaml 中定义的容器镜像:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"

 

总结:所以实际操作中,大多数情况下,我们只需要通过操作Chart.yaml和values.yaml文件进行自定义chart的设置,其他文件均是由变量来获取values.yaml中的值 

(2)进行模板文件的修改,生成自定义chart 

vim nginx/Chart.yaml
apiVersion: v2
name: nginx                     #chart名字
description: A Helm chart for Kubernetes
type: application               #chart类型,application或library
version: 0.1.0                  #chart版本
appVersion: 1.16.0              #application部署版本

 vim nginx/values.yaml
replicaCount: 1
 
image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: "latest"                 #设置镜像标签
 
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
 
serviceAccount:
  create: true
  annotations: {}
  name: ""
 
podAnnotations: {}
 
podSecurityContext: {}
  # fsGroup: 2000
 
securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000
 
service:
  type: ClusterIP
  port: 80
 
ingress:
  enabled: true                 #开启 ingress
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: www.test.com         #指定ingress域名
      paths:
        - path: /
          pathType: Prefix      #指定ingress路径类型
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local
 
resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi
 
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80
 
nodeSelector: {}
 
tolerations: []
 
affinity: {}

(3)进行chart打包 

//打包 chart
helm lint nginx        #检查依赖和模版配置是否正确
 
helm package nginx     #打包 chart,会在当前目录下生成压缩包 nginx-0.1.0.tgz

 

(4)利用自定义chart包进行k8s资源部署 

helm install nginx ./nginx --dry-run --debug    #使用 --dry-run 参数验证 Chart 的配置,并不执行安装
 
helm install nginx ./nginx -n default           #部署 chart,release 版本默认为 1
或者
helm install nginx ./nginx-0.1.0.tgz
 
#可根据不同的配置来 install,默认是 values.yaml
helm install nginx ./nginx -f ./nginx/values-prod.yaml

(5)部署 ingress

wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml

kubectl get pod,svc -n ingress-nginx
kubectl get ingress

 

 进行客户机测试:(随便启用一台k8s集群以外的客户机

vim /etc/hosts
192.168.73.107 www.test.com 

(6)进行修改变动,进行chart的升级更新 

//修改为 NodePort 访问后,升级
vim nginx/values.yaml
service:
  type: NodePort
  port: 80
  nodePort: 30080
 
ingress:
  enabled: false
 
vim nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ include "nginx.fullname" . }}
  labels:
    {{- include "nginx.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
      nodePort: {{ .Values.service.nodePort }}              #指定 nodePort
  selector:
    {{- include "nginx.selectorLabels" . | nindent 4 }}

 

 

 
升级 release,release 版本加 1
helm upgrade nginx nginx 

 

 

进行访问测试:

 

 (7)自定义chart的版本回滚 (根据release版本)

helm history nginx              #查看 release 版本历史
 
helm rollback nginx 1           #回滚 release 到版本1
 
#通常情况下,在配置好 templates 目录下的 kubernetes 清单文件后,后续维护一般只需要修改 Chart.yaml 和 values.yaml 即可。

 在命令行使用 --set 指定参数来部署(install,upgrade)release
#注:此参数值会覆盖掉在 values.yaml 中的值,如需了解其它的预定义变量参数,可查看 helm 官方文档。
helm upgrade nginx nginx --set image.tag='1.15' (相当于k8s中打补丁设置的方式)

4. Helm 的私有仓库-Habor
 

 前面介绍了Habor作为docker镜像的私有仓库,其实Habor还可以成为Helm的私有仓库,用来存放打包好的chart包

具体部署步骤

(1)在新主机上安装habor和docker-compose(前提是已经安装好docker) 

 

//安装 harbor
#上传 harbor-offline-installer-v1.9.1.tgz 和 docker-compose 文件到 /opt 目录
cd /opt
cp docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose
 
tar zxf harbor-offline-installer-v1.9.1.tgz
cd harbor/

 

vim harbor.yml
hostname: 192.168.73.108
harbor_admin_password: Harbor12345     #admin用户初始密码
data_volume: /data                     #数据存储路径,自动创建
chart:
  absolute_url: enabled                #在chart中启用绝对url
log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor          #日志路径
 
#安装带有 Clair service 和 chart 仓库服务的 Harbor
./install.sh --with-clair --with-chartmuseum

(2)在helm主机上安装好push插件 

#在线安装
helm plugin install https://github.com/chartmuseum/helm-push
 
#离线安装
wget https://github.com/chartmuseum/helm-push/releases/download/v0.8.1/helm-push_0.8.1_linux_amd64.tar.gz
 
mkdir -p ~/.local/share/helm/plugins/helm-push
tar -zxvf helm-push_0.8.1_linux_amd64.tar.gz -C ~/.local/share/helm/plugins/helm-push
 
helm repo ls

(3)在habor主机创建项目,在helm主机添加chart仓库 

打开浏览器:访问http://192.168.73.108,新建项目 

 

 

在helm主机上进行操作 :

#添加仓库
helm repo add harbor http://192.168.73.108/chartrepo/chart_repo --username=admin --password=Harbor12345
#注:这里的 repo 的地址是<Harbor URL>/chartrepo/<项目名称>,Harbor 中每个项目是分开的 repo。如果不提供项目名称, 则默认使用 library 这个项目。
 

 

(4)进行推送拉取测试 

推送chart包测试:

#推送 chart 到 harbor 中
cd /opt/helm
helm push nginx-0.1.0.tgz harbor
 

 

拉取chart包测试: 

注意:第一次拉取私有仓库chart包时,需要先进行helm repo update  更新helm仓库源

 

rm -f nginx-0.1.0.tgz
mkdir repo.bak
mv nginx/  ./repo.bak
 
#因为harbor仓库是第一次使用,需要先对仓库源进行更新
helm repo update
helm pull  harbor/nginx

 

 

 Helm的命令总结

(1)Helm的常用命令总结

 
helm           #查看helm基本操作命令
helm version   #查看helm的版本
helm env       #查看环境变量
helm create chartName    #创建chart目录(含基本配置文件和目录)
helm package chartDir    #将chart目录打包
helm template chartName  #渲染template目录下的模板文件(即将这些模板文件的字段内容用values.yaml填充,然后直接输出到终端)
 
helm search repo keyword   #根据关键字检索chart包
helm search hub keyword
#上面2个命令仅仅在第3个字段有区别,repo表示在本地所添加的仓库中进行检索;hub表示在Helm Hub中进行检索。
 
helm list  #查看发布到k8s中的chart对应的release
 
helm push chart.tgz repoName    上传chart到chart仓库
例:helm push demo.tgz harbor-10.30.12.211 --username=admin --password=Harbor12345
#有些仓库是有账号密码验证的,所以需要加上账号、密码的参数(比如Harbor提供的chart仓库功能,可参考下面的私有仓库搭建先搭建一个私有仓库出来,再进行仓库相关命令的测试)
 
命令:helm pull repoName/keyword    #从chart仓库中拉取chart到本地
例:helm pull harbor-10.30.12.211/demo
#harbor-10.30.12.211/demo的结构是本地起的仓库名/chart包的名字前缀,只要在harbor-10.30.12.211仓库中含有demo为前缀的chart包,就会被下载到本地
 
helm lint chartName    #检查chart包中的文件内容是否正确(即该chart包去k8s中是否能够成功安装部署)
#包可以是chart目录、chart压缩包
 
helm install releaseName chartName    #将chart包发布到k8s集群中安装部署
#releaseName为release的名字,chartName为chart包名,chart可以是未打包的chart,也可以是打包的chart,也可以是仓库中的chart。【chart和release的关系可以大致理解为程序和进程的关系,一个是静态的,一个是动态的】
helm install chartName --generate-name
#可以不指定release的名字,只需要指定–generate-name即可随机生成一个名字
#创建完后可以使用helm list查看是否有对应的release
 
helm uninstall releaseName   #将部署到k8s中的release卸载掉
#卸载完后使用helm list查看relDemo是否被删除了,同时可以使用kubectl get pods查看相应的pod等与release相关的资源是否全部删除干净
 
helm upgrade releaseName chartName     #将部署到k8s中的release升级,即相当于应用升级
#relName指定一个release,该release对应一个k8s中的应用,chartName指定一个chart包,整个过程为直接使用指定的chart包替换部署release。就helm而言release还是原来那个,不过对应的chart包被替换了。对k8s而言,仅仅是将原先资源删除,然后用新的chart包创建资源。
#使用helm list查看release的CHART字段是否更新,同时可以使用kubectl get pods查看相应的pod等与release相关的资源是否全部更新(看名字、运行时间)
 
helm rollback releaseName revision   #将release回退到前一个或若干个版本(k8s中会同步回退)
#revision为第几个版本,1表示第一个版本,2表示第二个版本,以此类推。通常回滚会搭配helm history releaseName使用,通过该命令查看所有的关于本release的发布历史,然后选择回退到哪个版本
#回滚成功后使用helm list查看该release的CHART和APP VERSION是否更新(具体得看chart中的chart.yaml中的version和appVersion有没有相应的修改),同时可以使用kubectl get pods查看相应的pod等与release相关的资源是否全部更新(看名字、运行时间)
 
helm history releaseName    #查看release的发布历史(包括安装、升级、回滚)
helm status releaseName     #查看release的基本信息

(2)查看chart包的操作命令

helm show chart chartName  #查看chart包中的chart.yaml文件内容
#chart包可以是本地的未打包的chart目录(即helm create 创建出来的chart目录),也可以是打包的chart压缩包(由helm package打包),也可以是保存在仓库中的chart包
 
helm show values chartName    #查看chart包中的values.yaml文件内容
#包同上有3种选择
 
helm show readme chartName     #查看chart包中README文件内容
#包同上有3种选择
 
helm show all chartName   #查看chart包中chart.yaml、values.yaml、README文件内容
#包同上有3种选择

(3)查看release指定内容(与helm show作用、格式相同)

 
helm get notes releaseName      #查看release的说明信息(相当于chart中的NOTES.TXT)
helm get manifest releaseName   #查看release在k8s中创建出来的资源
helm get hooks releaseName      #查看release的回调创建资源
helm get values releaseName     #查看release的values配置
helm get all releaseName        #查看上述所有内容

(4)helm plugin —— 插件管理

 

 
helm plugin list     #查看本地安装好的插件 (插件管理)
 
helm plugin install pluginURL    #安装插件
例:helm plugin install https://github.com/chartmuseum/helm-push
#最后的url地址为插件的下载地址,可参考 https://github.com/chartmuseum/helm-push
 
helm plugin uninstall pluginName   #卸载插件
helm plugin update pluginName   #更新插件,将插件升级到最新版本
#在下载插件的时候会保存插件及其下载地址,更新的时候使用原本的下载地址直接下载最新版本替换

(5)helm repo —— 仓库管理

helm repo list     #(仓库管理)查看添加的chart仓库,可在这些chart仓库中拉取chart(实际上就相当于一个应用的安装包)
 
helm repo add repoName repoURL     #本地添加chart仓库
例:helm repo add abc http://mirror.azure.cn/kubernetes/charts/
#repoName是你自己起的一个名字,用来代表这个repoURL,后续操作仓库的命令中直接用repoName来代替repoURL,只要指定了repoName,就表示要去操作repoName指向的repoURL的仓库
 
helm repo remove repoName  #本地删除chart仓库
 
helm repo update   #将本地所添加的chart仓库的最新信息缓存到本地
#helm search命令是检索某仓库中的chart包,假设仓库中一开始是没有所指定的chart包,所以helm search是检索不到的。这时候如果将chart包上传至该仓库,本地需要执行一遍helm repo update以更新本地的缓存数据才能检索到该指定的chart,因为helm search就是读取本地缓存数据的
 
helm repo index repoDir --url=repoURL     #根据指定仓库目录下的chart包生成index.yaml索引文件
例:helm repo index repo --url=http://192.168.73.108:8080/
#repoDir指定一个仓库的目录,该目录用来存放chart包及索引文件index.yaml。url指定仓库的访问路径,生成的索引文件中会以该url为地址前缀拼接上chart包名作为chart包的访问路径

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

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

相关文章

Profibus DP主站转Modbus TCP网关profibus从站地址范围

远创智控YC-DPM-TCP网关。这款产品在Profibus总线侧实现了主站功能&#xff0c;在以太网侧实现了ModbusTcp服务器功能&#xff0c;为我们的工业自动化网络带来了全新的可能。 远创智控YC-DPM-TCP网关是如何实现这些功能的呢&#xff1f;首先&#xff0c;让我们来看看它的Profib…

Linux 学习记录52(ARM篇)

Linux 学习记录52(ARM篇) 本文目录 Linux 学习记录52(ARM篇)一、汇编语言相关语法1. 汇编语言的组成部分2. 汇编指令的类型3. 汇编指令的使用格式 二、基本数据处理指令1. 数据搬移指令(1. 格式(2. 指令码类型(3. 使用示例 2. 立即数(1. 一条指令的组成 3. 移位操作指令(1. 格式…

Meta 最新发布 LLaMA 2(允许商业化)

2023年7月18日&#xff0c;Meta 发布了LLaMA 2&#xff0c;包含7B&#xff0c;13B&#xff0c;70B三种参数&#xff08;34B暂时还未发布&#xff09;。 官方&#xff1a; https://ai.meta.com/llama/ 论文&#xff1a;Llama 2: Open Foundation and Fine-Tuned Chat Models 模型…

网络编程——RPC与HTTP基本介绍、历史追溯、主流应用场景、对比分析、为什么还需要使用RPC

一、HTTP与RPC基本介绍 HTTP协议&#xff08;Hyper Text Transfer Protocol&#xff09;超文本传输协议&#xff1a; 一个用于在网络上交换信息的标准协议&#xff0c;它定义了客户端(例如浏览器)和服务器之间的通信方式。如平时上网在浏览器上敲个网址url就能访问网页&#x…

关于电脑显示器屏幕看不出灰色,灰色和白色几乎一样无法区分,色彩调整方法

问题&#xff1a; 电脑显示器屏幕看不出灰色&#xff0c;灰色和白色几乎一样无法区分。白色和灰色有色差。 解决方法&#xff1a; 打开“控制面板” ->“色彩管理” ->“高级” ->“校正显示器” 在下一步调节中调成中间这一个实例的样子就可以了 进行微调&#x…

如何用3D格式转换工具HOOPS Exchange读取颜色和材料信息?

作为应用程序开发人员&#xff0c;非常希望导入部件的图形表示与它们在创作软件中的外观尽可能接近。外观可以在每个B-Rep面的基础上指定&#xff0c;而且&#xff0c;通过装配层次结构的特定路径可以在视觉外观上赋予父/子覆盖。HOOPS ExchangeHOOPS Exchange可捕获有关来自各…

亚信科技荣任「DBL电信行业工作组」副组长单位,AntDB数据库连年入选《中国数据库产品图谱》

日前&#xff0c;“2023可信数据库发展大会”在京圆满召开。亚信科技凭借自研的电信级核心交易数据库AntDB在通信行业15年的技术积累和行业贡献&#xff0c;成功当选为数据库应用创新实验室&#xff08;DBL&#xff09;电信行业工作组副组长单位。AntDB数据库连续两年入选《全球…

11、动手学深度学习——语言模型和数据集:代码详解

我们了解了如何将文本数据映射为词元&#xff0c;以及将这些词元可以视为一系列离散的观测&#xff0c;例如单词或字符。 假设长度为 T T T的文本序列中的词元依次为 x 1 , x 2 , … , x T x_1, x_2, \ldots, x_T x1​,x2​,…,xT​。于是&#xff0c; x t x_t xt​&#xff08…

Type-C带充电的OTG转接器方案 LDR6028

近些年随着社会生活水平提高&#xff0c;每个人的的电子设备逐渐的多了起来&#xff0c;各大品牌都在发售自家品牌的全家桶。手机、平板、笔记本电脑、智能手表、无线耳机、任天堂Switch、索尼PS5等电子设备一种不落。 那么多的电子设备基本来说都是需要充电&#xff0c;比如手…

求出0~100000之间的所有“水仙花数”并输出

求出0~100000之间的所有“水仙花数”并输出。 “水仙花数”是指一个N位数&#xff0c;其各位数字的n次方之和正好等于该数本身。 如&#xff1a;1531^3 5^3 3^3 , 则153是一个“水仙花数” 先来了解一下水仙花数的概念&#xff1a; 水仙花数只是自幂数的一种&#xff0c;严…

匿名内部类/Lambda Java和Kotlin谁会导致内存泄漏?

作者&#xff1a;小鱼人爱编程 前言 内存泄漏是程序界永恒的话题&#xff0c;对于Android开发来说尤为重要&#xff0c;想让你的App表现得更优雅&#xff0c;了解并治理内存泄漏问题势在必行。 通过本篇文章&#xff0c;你将了解到&#xff1a; 何为内存泄漏?Android 常见内存…

动态规划---子序列问题

一)最长递增子序列: 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 算法原理: 1.定义一个状态表示:经验题目要求 dp[i]表示&#xff0c;以i位置为结尾&#xff0c;最长递增子序列的长度 中心思路就是找到以i位置为结尾的所有递增子序列&#xff0c;然后找到递增…