如何减少极狐GitLab 容器镜像库存储?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有:
- 极狐GitLab 中文文档
- 极狐GitLab 中文论坛
- 极狐GitLab 官网
减少容器镜像库存储 (BASIC ALL)
未清理的容器镜像库会随着时间的推移而变大。添加大量镜像或标签时:
- 获取可用标签或镜像列表变得更慢。
- 它们占用服务器上大量的存储空间。
我们建议删除不必要的镜像和标签,并设置清理策略,自动管理您的容器镜像库使用情况。
View container registry usage
DETAILS:
Tier: Free, Premium, Ultimate
Offering: GitLab.com
- Introduced in GitLab 15.7
To view the storage usage for the container registry:
1.On the left sidebar, select Search or go to and find your project.
2.Select Settings > Usage Quotas.
You cannot view container registry usage for self-managed instances, but this is
proposed in epic 5521.
容器仓库使用率是如何计算的?
存储在容器镜像仓库中的镜像层在根命名空间级别中会被去重。
在如下情况下,镜像仅会被计算一次:
- 您在同一仓库中标记同一镜像多次。
- 您在同一根命名空间中的不同仓库中标记同一镜像。
在如下情况下,镜像层仅会被计算一次:
- 您在相同的容器仓库、项目或群组中跨多个镜像共享镜像层。
- 您在不同的容器仓库中跨多个镜像共享镜像层。
仅由被标签的镜像引用的镜像层会被计算出来。未标记的镜像和任何只由它们引用的镜像层都会受到在线垃圾收集的影响。未标记的镜像层会在 24 小时内未引用时自动删除。
存储在存储后端中的镜像层以源(通常是被压缩的)格式存储。这意味着任何给定的镜像层的测量大小应与相应的镜像清中显示的大小相匹配。
当命名空间中任何仓库中的任何标签被推送或删除时,命名空间使用率会在几分钟后刷新。
延迟刷新
没有办法实时精确计算大型命名空间下容器镜像仓库的使用。要想让这些命名空间的维护者看到容器仓库的使用率,有一个延迟回调机制。
如果命名空间的使用率无法精确计算,极狐GitLab 将回退到延迟方法。在延迟方法中,显示的使用量是命名空间中的所有唯一镜像层的 总和。未标记的镜像层不会被忽略。结果就是,显示的使用量可能不会在删除标签后大量变化。反之,大小值仅在以下情况下更改:
- 会运行一个自动化的垃圾清理进程并删除未标记的镜像层。在用户删除标签后,垃圾收集进程将在 24 小时后开始运行。在该运行过程中,以前标记的镜像被分析,如果没有其他标记的镜像引用它,则删除它们的镜像层。如果任何层被删除,命名空间的使用量会更新。
- 命名空间的容器镜像使用量缩小到可以精确测量时,极狐GitLab 会自动切换到延时使用量测量方法。
清理策略
- 于 15.0 版本,所需权限从开发者更改为维护者。
清理策略是一项计划作业,可用于从 Container Registry 中删除标签。对于定义它的项目,匹配正则表达式 pattern 的标签将被删除。底层镜像层和镜像保留。
管理员可以使用垃圾收集与 -m
开关。
启用清理策略
WARNING:由于性能原因,启用的清理策略在 JihuLab.com 上为没有容器镜像的项目上自动禁用。
清理策略工作原理
清理策略会收集 Container Registry 中的所有标签并排除标签,直到只剩下要删除的标签为止。
清理策略根据标签名称搜索镜像。对完整路径的支持尚未实现,但允许您清理动态命名的标签。
清理策略:
1.在列表中收集给定仓库的所有标签。
2.从列表中排除名为 latest
的标签。
3.评估 name_regex
(要过期的标签),从列表中排除不匹配的名称。
4.从列表中排除任何与 name_regex_keep
值匹配的标签(要保留的标签)。
5.排除任何没有 manifest 的标签(不是 UI 中选项的一部分)。
6.按 created_date
对剩余标签进行排序。
7.根据 keep_n
值(要保留的标签数)从列表中排除 N 个标签。
8.从列表中排除比 older_than
值(过期间隔)更新的标签。
9.最后,将列表中剩余的标签从 Container Registry 中删除。
WARNING:私有化部署实例支持符合 Docker Registry HTTP API V2 规范的第三方容器镜像库。但是,该规范不包括标签删除操作。
清理策略工作流示例
清除策略的保留和删除规则之间的交互可能很复杂。
例如,对于具有以下清理策略配置的项目:
-
保留最新的:每个镜像名称 1 个标签
-
保留匹配标签:
production-.*
-
删除早于以下时间的标签:7 天
-
删除匹配的标签:
.*
以及带有以下标签的容器仓库:
-
latest
,2 小时前发布。 -
production-v44
,3 天前发布。 -
production-v43
,6 天前发布。 -
production-v42
,11 天前发布。 -
dev-v44
,2 天前发布。 -
dev-v43
,5 天前发布。 -
dev-v42
,10 天前发布。 -
v44
,昨天发布。 -
v43
,12 天前发布。 -
v42
,20 天前发布。
在此示例中,将在下一次清理运行中删除的标签是 dev-v42
、v43
和 v42
。
适用于此优先级规则的解释如下:
1.保留规则具有最高优先级。匹配 任何 规则时必须保留标签。
-
latest
标签一定会保留,因为latest
标签总是被保留。 -
production-v44
、production-v43
和production-v42
标签一定会保留,因为它们符合 保持标签匹配 规则。 -
v44
标签一定会保留,因为它是最新的,符合 保留最新的 规则。
2.删除规则的优先级较低,只有在 所有 规则匹配时才会删除标签。对于不匹配任何保留规则的标签(dev-44
、dev-v43
、dev-v42
、v43
和 v42
):
-
dev-44
和dev-43
不 匹配 删除早于以下时间的标签,并被保留。 -
dev-v42、v43 和 v42 同时匹配 删除早于以下时间的标签 和 删除匹配的标签 规则,因此可以删除这三个标签。
创建清理策略
您可以在 API 或 UI 中创建清理策略。
要在 UI 中创建清理策略:
1.对于您的项目,转到 设置 > 软件包与镜像库。
2.在 清理策略 部分中,选择 设置清理规则。
3.填写字段。
字段 | 描述 |
---|---|
切换 | 打开或关闭策略。 |
运行清理 | 策略应该多久运行一次。 |
保留最近的 | 总是为每个镜像保留多少标签。 |
保留匹配标签 | 确定要保留哪些标签的正则表达式 pattern。latest 标签总是被保留。对于所有标签,使用 .* 。请参阅其他 regex pattern 示例。 |
删除早于以下时间的标签 | 仅删除早于 X 天的标签。 |
删除匹配的标签 | 确定要删除哪些标签的正则表达式 pattern。该值不能为空。对于所有标签,使用 .* 。请参阅其他 regex 模式示例。 |
4.点击 保存。
根据您选择的时间间隔,策略将被安排运行。
NOTE:如果您编辑策略并再次单击 保存,则会重置间隔。
正则表达式 pattern 示例
清理策略使用正则表达式 pattern 来确定应在 UI 和 API 中保留或删除哪些标签。
正则表达式 pattern 会自动用 \A
和 \Z
锚点包围。不要在正则表达式模式中包含任何 \A
、\Z
、^
或 $
标记,因为它们不是必需的。
以下是您可能想要使用的正则表达式 pattern 示例:
- 匹配所有标签:
.*
这是到期正则表达式的默认值。
- 匹配以
v
开头的标签:
v.+
- 只匹配名为
main
的标签:
main
- 匹配已命名或以
release
开头的标签:
release.*
- 匹配以
v
开头、名为main
或以release
开头的标签:
(?:v.+|main|release.*)
设置清理限制以节约资源
- 功能标志
container_registry_expiration_policies_throttling
移除于 15.0 版本。
清理策略作为后台进程执行。此过程很复杂,根据要删除的标签数量,该过程可能需要一些时间才能完成。
为了防止服务器资源匮乏,可以使用以下应用程序设置:
-
container_registry_expiration_policies_worker_capacity
:同时运行的清理 worker 的最大数量,必须大于或等于0
。我们建议从一个较小的数字开始,并在监控后台 worker 使用的资源后增加它。要删除所有 worker 而不执行清理策略,请将其设置为0
。默认值为4
。 -
container_registry_delete_tags_service_timeout
:清理过程删除一批标签可以花费的最长时间(以秒为单位)。默认值为250
。 -
container_registry_cleanup_tags_service_max_list_size
:一次执行中可以删除的最大标签数。 必须在另一次执行中删除附加标签。我们建议从一个较小的数字开始,并在监控容器镜像被正确删除后增加它。 默认值为200
。 -
container_registry_expiration_policies_caching
: 在执行策略期间启用或禁用标签创建时间戳缓存。缓存的时间戳存储在 Redis 中。默认启用。
对于私有化部署实例,可以在 Rails 控制台中更新这些设置:
ApplicationSetting.last.update(container_registry_expiration_policies_worker_capacity: 3)
或者,一旦限制被启用,它们在管理中心可用:
1.在左侧边栏中,选择 搜索或转到。
2.选择 管理中心。
3.进入 设置 > CI/CD > 容器镜像库。
使用清理策略 API
您可以使用 GitLab API 设置、更新和禁用清理策略。
示例:
- 选择所有标签,每个镜像至少保留 1 个标签,清理任何超过 14 天的标签,每月运行一次,保留名称为
main
的所有镜像并启用策略:
curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_access_token>" \--data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":".*","name_regex_keep":".*-main"}}' \"https://gitlab.example.com/api/v4/projects/2"
使用 API 时 cadence
的有效值为:
-
1d
(每天) -
7d
(每周) -
14d
(每两周) -
1month
(每月) -
3month
(每季度)
使用 API 时 keep_n
(每个镜像名称保留的标签数量)的有效值是:
1
5
10
25
50
100
使用 API 时 older_than
的有效值(距离自动删除标签的天数)为:
-
7d
-
14d
-
30d
-
90d
7
与外部容器镜像库一起使用
使用外部容器镜像库时,在项目上运行清理策略可能会有一些性能风险。
如果一个项目运行一项删除数千个标签的策略,则后台作业可能会被备份或完全失败。
如果您确信要清理的标签数量最少,建议您只为 12.8 之前创建的项目启用容器清理策略。
清理策略故障排查
Something went wrong while updating the cleanup policy.
如果您看到此错误消息,请检查正则表达式 pattern,确保它们有效。
极狐GitLab 在清理策略中使用 RE2 语法 作为正则表达式。您可以使用 regex101 regex tester 测试它们。
查看一些常见的 regex 模式示例。
清理策略不删除任何标签
这背后可能有不同的原因:
-
在 13.6 及更早版本中,当您运行清理策略时,您可能希望它会删除标签,但事实并非如此。当清理策略被保存而不编辑 删除匹配的标签 字段中的值时,就会发生这种情况。该字段有一个灰色的
.*
值作为占位符。除非在字段中明确输入了.*
(或其他正则表达式模式),否则会提交一个nil
值,此值可防止保存的清理策略匹配任何标签。作为解决方法,请编辑清理策略。在 删除匹配的标签 字段中,输入.*
并保存,此值表示应删除所有标签。 -
如果您在私有化部署实例上并且容器镜像库中有 1000 多个标签,您可能会遇到 Container Registry 令牌过期问题,并在日志中显示
error authorizing context: invalid token
。
要解决此问题,有两种解决方法:
-
如果您使用的是 13.9 或更高版本,您可以为清理策略设置限制。这样可以及时限制清理执行,并避免过期令牌错误。
-
延长 Container Registry 身份验证令牌的到期延迟。默认为 5 分钟。您可以通过在 Rails 控制台中运行
ApplicationSetting.last.update(container_registry_token_expire_delay: <integer>)
来设置自定义值,其中<integer>
是所需的分钟数。请注意,通过扩展此值会增加撤销权限所需的时间。
如果以前的修复不起作用或者您使用的是早期版本,您可以生成要删除的标签列表,然后使用该列表删除标签。请按照下列步骤操作:
1.运行以下 shell 脚本。for
循环之前的命令确保在启动循环时始终重新初始化 list_o_tags.out
。运行此命令后,所有标签的名称都将在 list_o_tags.out
文件中:
# Get a list of all tags in a certain container repository while considering [pagination](../../../api/index.md#pagination)
echo -n "" > list_o_tags.out; for i in {1..N}; do curl --header 'PRIVATE-TOKEN: <PAT>' "https://gitlab.example.com/api/v4/projects/<Project_id>/registry/repositories/<container_repo_id>/tags?per_page=100&page=${i}" | jq '.[].name' | sed 's:^.\(.*\).$:\1:' >> list_o_tags.out; done
如果您有 Rails 控制台访问权限,则可以输入以下命令来检索受日期限制的标签列表:
output = File.open( "/tmp/list_o_tags.out","w" )
Project.find(<Project_id>).container_repositories.find(<container_repo_id>).tags.each do |tag|output << tag.name + "\n" if tag.created_at < 1.month.ago
end;nil
output.close
这组命令创建了一个 /tmp/list_o_tags.out
文件,其中列出了 created_at
日期超过一个月的所有标签。
2.从 list_o_tags.out
文件中删除您要保留的所有标签。例如,您可以使用 sed
来解析文件并删除标签。
# Remove the `latest` tag from the file
sed -i '/latest/d' list_o_tags.out# Remove the first N tags from the file
sed -i '1,Nd' list_o_tags.out# Remove the tags starting with `Av` from the file
sed -i '/^Av/d' list_o_tags.out# Remove the tags ending with `_v3` from the file
sed -i '/_v3$/d' list_o_tags.out
如果您运行的是 macOS,则必须将 .bak
添加到命令中。 例如:
# Remove the `latest` tag from the file
sed -i .bak '/latest/d' list_o_tags.out# Remove the first N tags from the file
sed -i .bak '1,Nd' list_o_tags.out# Remove the tags starting with `Av` from the file
sed -i .bak '/^Av/d' list_o_tags.out# Remove the tags ending with `_v3` from the file
sed -i .bak '/_v3$/d' list_o_tags.out
3.仔细检查 list_o_tags.out
文件以确保它只包含您要删除的标签。
4.运行此 shell 脚本,删除 list_o_tags.out
文件中的标签:
# loop over list_o_tags.out to delete a single tag at a time
while read -r LINE || [[ -n $LINE ]]; do echo ${LINE}; curl --request DELETE --header 'PRIVATE-TOKEN: <PAT>' "https://gitlab.
相关文章:
如何减少极狐GitLab 容器镜像库存储?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 减少容器镜像库存储 (BASIC ALL) 未清理的容器镜像库会随着时间的推移而变大。添加大量镜像或标签时: 获取可用标…...

计算机学习路线与编程语言选择(信息差)
——授人以鱼不如授人以渔 计算机学习公式:1/3科班思维 1/3路线选择 1/3工程能力 好工作随便找(来自B站小毛毛熊) 本文主要是路线选择!!!下面开始吧。 面向岗位学习!到招聘网站看看有哪些…...

【redis】redis 手动切换主从
场景一: 测试需要,需要手动切换主从 在redis节点: $ redis-cli -h xx.xx.xx.xx -p XX -a XX shutdown 不要直接关闭redis进程,使用 shutdown ,能在进程关闭前持久化内存中的数据 待主从切换完毕后࿱…...
基于设备指纹识别的反爬虫技术:给设备办 “身份证”
传统的封禁 IP、验证码等反爬虫手段已逐渐失效,基于设备指纹识别的反爬虫技术应运而生,成为守护数据安全的新防线。它如同给每个设备办一张独一无二的 “身份证”,精准区分正常用户与爬虫工具。 一、基础参数采集:构建设备指纹的…...
SpringAI框架中的RAG知识库检索与增强生成模型详解
SpringAI框架中的RAG知识库检索与增强生成模型详解 一、RAG简介 RAG(Retrieval-Augmented Generation)可以通过检索知识库,克服大模型训练完成后参数冻结的局限性,携带知识让大模型根据知识进行回答。 二、SpringAI框架支持的R…...
【造包工具】【Xcap】精讲Xcap构造分片包(IPv4、ipv6、4G\5G等pcap均可),图解超赞超详细!!!
目录 前言 1. XCap工具概念介绍 2. Xcap环境说明 2.1 新建报文组 2.2 导入数据包 2.3 查看报文组 2.4 复制删除报文组 3. 构造分片包 3.1 造普通/外层分片步骤: 3.2 造内层分片步骤 3.2.1 建立一个新报文 3.2.2 将组装的新报文分片 3.2.3 替换原始包内层部分 3.2…...

第三节:Vben Admin 最新 v5.0 对接后端登录接口(下)
文章目录 前言一、处理请求头Authorization二、/auth/user/info 接口前端接口后端接口三、/auth/codes 接口1.前端2.后端四、测试接口前言 上一节内容,实现了登录的/auth/login 接口,但是登陆没有完成,还需要完成下面两个接口。才能完成登录。 一、处理请求头Authorizatio…...

爬虫学习————开始
🌿自动化的思想 任何领域的发展原因————“不断追求生产方式的改革,即使得付出与耗费精力越来愈少,而收获最大化”。由此,创造出方法和设备来提升效率。 如新闻的5W原则直接让思考过程规范化、流程化。或者前端框架/后端轮子的…...

Ubuntu18.04搭建samda服务器
一.什么是Samba服务器? Samba服务器是一种基于开源协议实现的网络共享服务软件,主要用于在不同操作系统(如Windows、Linux、Unix)之间实现文件和打印机共享功能。其核心目标是解决跨平台资源共享的兼容性问题,尤其是在…...
K8S扩缩容及滚动更新和回滚
目录: 1、滚动更新1、定义Deployment配置2、应用更新 2、版本回滚1. 使用kubectl rollout undo命令 3、更新暂停与恢复1、暂停更新2、更新镜像(例如,使用kubectl set image命令)3、恢复更新 4、弹性扩缩容1、扩容命令2、缩容命令3…...
一文掌握 LVGL 9 的源码目录结构
文章目录 📂 一文掌握 LVGL 9 的源码目录结构🧭 顶层目录概览📁 1. src/ — LVGL 的核心源码(🔥重点)📁 2. examples/ — API 示例📁 3. demos/ — 综合演示项目📁 4. do…...

2025-05-10-FFmepg库裁切有水印的视频
裁后 代码 import subprocess# 文件路径 input_video_path "bg_video.mp4" output_video_path "output_video_cropped.mp4"# 裁剪视频下方的水印 def crop_video(input_video_path, output_video_path, crop_height):# 获取视频的分辨率def get_video…...
Vue3 路由配置与跳转传参完整指南
目录 一、路由配置 1. 基本路由配置 2. 动态路由配置 3. 可选参数配置 二、路由跳转与传参 1. 声明式导航 (模板中) 2. 编程式导航 (JavaScript中) 三、参数接收 1. 接收动态路由参数 2. 接收查询参数 3. 监听参数变化 四、高级用法 1. 路由元信息 2. 路由守卫控…...

opencv+opencv_contrib+cuda和VS2022编译
本文介绍使用OpenCV和OpenCV_Contrib源码及Cuda进行编译的过程,编译过程中会用到OpenCV、OpenCV_Contrib、CUDA Toolkit、cuDNN、Cmake、VS2022等工具,最终编译OpenCV的Cuda版本。 一、OpenCV下载地址 OpenCV官网下载地址:https://opencv.org/releases…...
《深挖Java中的对象生命周期与垃圾回收机制》
大家好呀!👋 今天我们要聊一个Java中超级重要的话题——对象的生命周期和垃圾回收机制。 一、先来认识Java世界的"居民"——对象 👶 在Java世界里,一切皆对象。就像现实世界中的人一样,每个Java对象也有自…...
C++中extern关键字详解:不同情况下的使用方式
在 C 中,extern 关键字主要用于声明变量或函数是在其他文件中定义的,从而可以在当前文件中使用这些变量或函数。下面详细介绍 extern 修饰全局变量、函数等的用法区别以及注意事项。 修饰全局变量 详细介绍 当 extern 用于修饰全局变量时,…...
【QT】深入理解 Qt 中的对象树:机制、用途与最佳实践
深入理解 Qt 中的对象树:机制、用途与最佳实践 在使用 Qt 编程时,你是否注意到很多对象可以设置“父对象”?比如: QPushButton* btn new QPushButton(parentWidget);这不是简单的层级结构,而是 Qt 强大而优雅的 对象…...
如何利用爬虫获得1688商品详情:实战指南
在电商运营和市场分析中,获取1688商品详情数据是一项重要任务。本文将详细介绍如何利用爬虫技术获取1688商品详情,包括准备工作、爬虫实现步骤以及注意事项。 一、准备工作 (一)注册1688开放平台账号 在1688开放平台注册开发者…...

网工实验——OSPF配置
网络拓扑图 配置 1.为每个路由器配置接口(略)(详细见RIP实验) 2.配置OSPF AR1 [AR1]ospf [AR1-ospf-1]area 1 [AR1-ospf-1-area-0.0.0.1]network 172.16.1.1 0.0.0.0 #精确配置网络,也可以像下面那条命令那样配置 …...

数据库系统概论-基础理论
数据库系统概述: 1、记录:计算机中表示和存储数据的一种格式或方法。 2、数据库(DataBase, DB):数据库是长期储存在计算机内、有组织、可共享的大量数据集合。可为各种用户共享。 3、数据库管理系统(Dat…...

从零开始学习人工智能(Python高级教程)Day6-Python3 正则表达式
一、Python3 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 在 Python 中,使用 re 模块来处理正则表达式。 re 模块提供了一组函数,允许你在字符串中进行模式匹配、搜索和替换操作。 r…...

Qt开发:项目视图(Item Views)的介绍和使用
文章目录 一、清单视图(List View)1.1 基本概念1.2 使用示例(文字列表)1.3 图标文字(图标模式)1.4 常用设置1.5 完整示例 二、树视图(Tree View)2.1 基本概念2.2 常用类简介2.3 快速…...
“ES7+ React/Redux/React-Native snippets“常用快捷前缀
请注意,这是一个常用的列表,不是扩展提供的所有前缀。最完整和最新的列表请参考扩展的官方文档或在 VS Code 中查看扩展的详情页面。 React (通常用于 .js, .jsx, .ts, .tsx): rfce: React Functional Component with Export Defaultrafce: React Arro…...

keepalived详细笔记
keepalived 是一种基于VRRP(虚拟路由器冗余协议)的高可用解决方案,主要是用于服务器的负载均衡和高可用性的保障,自动将服务切换到备份服务器上,确保业务的连续性。 工作原理: VRRP协议:一组路…...

xLua笔记
Generate Code干了什么 肉眼可见的,在Asset文件夹生成了XLua/Gen文件夹,里面有一些脚本。然后对加了[CSharpCallLua]的变量寻找引用,发现它被XLua/Gen/DelegatesGensBridge引用了。也可以在这里查哪些类型加了[CSharpCallLua]。 public over…...

一周学会Pandas2 Python数据处理与分析-Pandas2数据排序操作
锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili Pandas 2提供了多种灵活的数据排序方法,主要针对 DataFrame 和 Series 对象。 1. 按值排序:s…...
obj = null; 赋值null之前没有其他引用指向obj对象,那么,当obj=null时,会被垃圾回收机制立即回收吗?
不会立即回收。 具体原因是: 赋值 obj null; 后,对象变成“不可达”,符合垃圾回收条件,但垃圾回收器并不会立刻回收它。垃圾回收是CLR自动控制的非确定性过程,什么时候执行回收取决于系统内存压力、GC策略、分代情况…...

lvm详细笔记
LVM简介 逻辑卷管理器,是Linux 系统中用于管理磁盘储存的关键技术。 LVM 则打破了磁盘分区一旦确定,其大小调整往往较为复杂,且难以灵活应对业务变化这种限制,它允许用户将多个物理分区组合卷组。例如,系统中的多个物…...

250505_HTML
HTML 1. HTML5语法与基础标签1.1 HTML5特性1.1.1 空白折叠现象1.1.2 转义字符 1.2 HTML注释1.3 基础标签1.3.1 div标签1.3.2 标题标签1.3.3 段落标签1.3.4 title1.3.5 meta 1.4 html骨架1.4.1 DTD1.4.2 html标签1.4.3 head与body标签 1.5 div标签详解1.5.1 常见class类名 2. 列…...

【HarmonyOS NEXT+AI】问答05:ArkTS和仓颉编程语言怎么选?
在“HarmonyOS NEXTAI大模型打造智能助手APP(仓颉版)”课程里面,有学员提到了这样一个问题: 鸿蒙的主推开发语言不是ArkTS吗,本课程为什么使用的是仓颉编程语言? 这里就这位同学的问题,统一做下回复,以方便…...