HarmonyOS 应用模块化设计 - 面试核心知识点

HarmonyOS 应用模块化设计 - 面试核心知识点

在 HarmonyOS 开发面试中,模块化设计是必考知识点。本文从面试官角度深度解析 HarmonyOS 应用模块化设计,涵盖 HAP、HAR、HSP 等核心概念,助你轻松应对技术面试!

🎯 面试高频问题:什么是模块化设计?

面试官常问:请解释 HarmonyOS 应用模块化设计的核心理念?

标准答案:

在大型软件工程中,模块化设计是现代软件工程的核心原则之一。通过将大型复杂系统拆解为更小、更易管理和理解的功能模块,提高系统的可维护性和可扩展性。

核心特点:

  • 多团队弱耦合协作开发
  • 契约化接口定义业务交互
  • 各团队业务独立发展,互不影响
  • 支持快速迭代演进

在 HarmonyOS 中的体现:

  • 模块化既是设计原则,也是开发实践
  • 将应用程序拆分为多个功能模块
  • 每个模块负责特定功能或特性
  • 支持独立开发、编译和部署
  • 可在不同设备上灵活组合和调用

📋 面试重点一:应用程序包结构

面试官:HarmonyOS 的应用包结构有哪些类型?

回答要点:

在进行模块化设计时,需要考虑 HarmonyOS 的应用包结构选型:

  • 开发态:源码组织方式
  • 编译态:编译过程中的包形态
  • 发布态:最终发布的应用包结构

关键概念:

  • HAP:HarmonyOS Ability Package
  • HAR:HarmonyOS Archive
  • HSP:HarmonyOS Shared Package

📋 面试重点二:Ability 应用组件设计

面试官:在多设备场景下,如何设计 Ability 组件?

🔥 面试要点 1:多任务多窗口场景

手机设备应用场景:

// 笔记应用 - 多页面复制场景
// 文档编辑应用 - 多文档同时编辑
// 导航应用 - 后台运行 + 主页查找
// 购物应用 - 客服界面快速切换
// 支付应用 - 信息查找复制

实际应用示例:

  • 笔记应用:可让用户将信息从笔记的一页复制到另一页
  • 文档编辑应用:可让用户同时打开编辑多个文档,可让用户将内容从一个文档复制或移动到另一个文档
  • 导航/打车应用:可以让导航后台运行,回到主页查找新的位置信息或其它信息
  • 购物类临时客服界面:可让用户通过任务管理快速从商品浏览页切换回到客服会话界面,避免用户一层层打开查找
  • 在应用支付/登录页面:用户可以切换到其他页面查找并复制相关信息

大屏设备应用场景:

// 视频播放器 - 播放 + 浏览列表
// 电子邮件 - 撰写 + 查看收件箱
// 地址簿 - 并排比较联系信息
// 阅读应用 - 多篇文章同时打开

实际应用示例:

  • 视频播放器应用:可让用户在观看播放内容的同时浏览其他可能感兴趣的视频列表
  • 电子邮件应用:可让用户在撰写电子邮件的同时查看收到的邮件列表
  • 地址簿应用:可让用户并排比较多个人员的联系信息
  • 阅读应用:可让用户在查阅所有标题概要后,打开多篇文章供稍后阅读

🔥 面试要点 2:Ability 设计原则

单 Ability 情况:

  • 单窗口类型应用
  • 多实例或指定实例的多任务应用
  • 普通游戏应用建议采用单 HAP 承载 UIAbility

多 Ability 情况:

  1. 多窗口类型应用

    • 每个窗口对应不同功能
    • 通过不同的 UIAbility 承载
    • 可设计为 Feature 类型的 HAP
  2. 应用扩展功能

    • 卡片和分享业务
    • 由系统提供的 ExtensionAbility 承载
    • 建议通过 Feature 类型的 HAP 承载

📋 面试重点三:应用模块化选型

面试官:如何选择合适的模块类型?

💡 面试技巧:三种模块类型对比

模块类型特点使用场景面试要点
Entry HAP应用主入口,默认存在且唯一应用启动入口每个应用必须有且仅有一个
Feature HAP独立功能模块,可按需加载独立功能、扩展能力支持独立安装和运行
HAR静态共享库代码复用、跨应用共享编译时打包进目标模块
HSP动态共享库按需加载、运行时共享独立安装,运行时加载

🎯 面试加分项:三种业务场景分析

1. 共享模块场景

图 1 多工程合作模式
多工程合作模式

面试官:什么是共享模块?

回答要点:

  • 某个功能模块需要在多个应用之间共享代码逻辑和资源
  • 通过公司私有的 OHPM 仓发布和集成编译产物
  • 支持多团队代码仓隔离开发
  • 只能使用 HAR 模块实现

2. 按需加载模块场景

面试官:按需加载模块有什么优势?

回答要点:

  • 减少包体积:首次下载不包含按需加载模块
  • 减少系统资源:节省 ROM 和 RAM 空间
  • 架构演进:模块间耦合关系清晰

技术选型:

  • Feature 类型的 HAP:可包含 Ability 组件
  • HSP:不包含 Ability 组件的按需加载

场景划分:

  • 单 HAP 场景:只包含一个 UIAbility 组件,优先采用单 HAP(Entry 类型的 HAP)来实现应用开发
  • 多 HAP 场景:要实现多任务承载多个 UIAbility 组件以及使用 ExtensionAbility 组件实现扩展功能

3. 多 HAP/HSP 引用相同 HAR 包的影响

图 2 HAP 包和 HSP 包分别引用相同 HAR 包
HAP和HSP引用HAR包

面试官:多模块引用同一 HAR 包会有什么问题?

回答要点:

  • 破坏 HAR 的单例模式
  • 导致方法在多个模块中重复执行
  • 增加应用冷启动时间

技术原理:
工程内包含三个模块:HAP 包作为应用主入口模块,HSP 包作为应用主界面显示模块,HAR_COMMON 集成了所有通用工具类,其中 funcResult 是 func 方法的执行结果。

当 HAP 和 HSP 模块同时引用 HAR_COMMON 模块时,会破坏 HAR 的单例模式。因此,HAP 和 HSP 模块在使用 HAR_COMMON 中的 funcResult 时,会导致 func 方法在两个模块加载时各执行一次,从而增加文件的执行时间。

优化方案:

图 3 切换为 HAP 包和 HAR 包分别引用相同 HAR 包
优化后的引用方式

优化建议:

  • 在多 HAP/HSP 引用相同 HAR 包的情况下,如果 HSP 包和 HAR 包均能满足业务需求,建议将 HSP 包改为 HAR 包
  • 若使用的 HSP 为集成态 HSP,可跳过该优化方案

性能测试代码示例:

// 1. 在被引用 HAR_COMMON 包中写入功能示例
// 2. 分别通过使用 HSP 包和 HAR 包来引用该 HAR_COMMON 包中的功能进行性能对比实验// 使用 HAP 包和 HSP 包引用该 HAR_COMMON 包中的功能
// HAP 包引用 HAR_COMMON 包中的功能// 使用 HAP 包和 HAR 包引用该 HAR_COMMON 包中的功能
// HAP 包引用 HAR_COMMON 包中的功能

性能分析:
使用 Launch 模板,对优化前后启动性能进行对比分析。

分析阶段的起点为启动 Ability(即 H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility 的开始点),阶段终点为应用第一次接到 vsync(即 H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int 的开始点)。

图 4 优化前,使用 HSP 包
优化前性能

图 5 优化后,使用 HAR 代替 HSP
优化后性能

性能对比数据:

方案阶段时长(毫秒)性能提升
(优化前)使用 HSP 包3125-
(优化后)使用 HAR 代替 HSP853.973% ↑

说明:
上述示例为凸显出差异,func 执行函数循环次数为 100000000,开发者实际修改后收益需根据实际情况测试。

测试数据表明,将 HSP 替换为 HAR 包后,应用启动耗时明显缩短。


📋 面试重点四:单 HAP 工程设计

面试官:单 HAP 工程如何进行模块化设计?

🔥 面试要点 1:不包含按需加载模块

图 6 非按需加载工程模型
非按需加载工程模型

设计原则:
对于不需要按需加载且仅包含一个 Entry 类型的 HAP 的 App,可以直接全部采用 HAR 进行开发设计。

说明:
这里提到的"仅有一个 HAP"是指一种设备类型仅包含一个 HAP,而不是指.app 文件包中仅有一个 HAP。.app 文件包可以包含其他设备的 HAP 包,例如手表和大屏设备的 HAP 包,以支持多设备分发。

架构特点:

  • 除产品模块层的 HAP 外,其他模块均为 HAR
  • 所有 HAR 最终编译进 HAP 中

优点:

  1. 无额外 HSP,节省安装和加载成本
  2. 利用 ArkTS 语言特性和编译器优化
  3. 代码工程架构简单,演进灵活

🔥 面试要点 2:包含按需加载模块

面试官:如何在单 HAP 工程中实现按需加载?

技术选型考虑:
在单 HAP 工程中实现按需加载功能时,对应的组件需采用 HSP 作为按需加载模块。HAR 是静态共享库,若多个 HAP 或 HSP 依赖同一份 HAR,该 HAR 在应用内会被重复存储。HSP 是动态共享库,其安装和加载会有性能损失,过多的 HSP 可能影响安装效率和 App 启动性能。需考虑 App 占用空间是否受限及启动性能的敏感度,根据业务需求在 App Size 与启动性能之间做好平衡。

说明:
这里提到的 App Size 指用户安装按需加载模块后,应用的整体大小。

App Size 优先方案:

图 7 公共依赖模块通过 HSP 模块壳承载
HSP模块壳方案

设计思路:
对于 App Size 优先的,可以考虑将公共依赖的模块封装在一个 HSP 模块壳中。

// 模块依赖关系示例
// hap_A 依赖:har_A + har_C + har_D
// hsp_B 依赖:har_B + har_C + har_D
// 解决方案:将 har_C 和 har_D 封装到 common_hsp 中

实现方案:
hap_A 依赖于独有的共享库 har_A,同时需要依赖于 har_C 和 har_D;而按需加载模块 hsp_B 依赖于独有的共享库 har_B,同时需要依赖于 har_C 和 har_D。

说明:
这里的共享库 har_A、har_B、har_C、har_D 不一定本地工程,有可能是从 ohpm 仓上依赖下载的。

因为 har_C 和 har_D 同时被 hap_A 和 hsp_B 工程所依赖,所以为了节省 App Size,可以将其封装到名为"common_hsp"的 Module 中,对外暴露 har_C 和 har_D 的接口,将 har_C 和 har_D 打包到 common_hsp 中,最后让 hap_A 和 hsp_B 依赖于 common_hsp 工程。common_hsp 工程是无实际意义的,它仅是一个"模块壳",是为了最小化 App Size 而存在的。

性能优先方案:

图 8 公共依赖模块使用 HAR 模块承载
HAR模块方案

设计思路:
对于性能优先的,则不需要再封装一个公共的 HSP 模块,直接依赖公共 HAR 包。

因为公共 HSP 包需要安装和加载,所以会有一些性能损耗。对于启动性能敏感型的应用,则将 hap_A 和 hsp_B 直接依赖于 har_C 和 har_D。最终编译产物里面有 2 个,hap_A.hap 和 hsp_B.hsp,但是这两个编译产物里面均会包含 har_C 和 har_D,App Size 会比采用公共 HSP 模型大。


📋 面试重点五:多 HAP 工程设计

面试官:多 HAP 工程的设计原则是什么?

💡 面试技巧:多 HAP 应用场景

适用场景:
对于同一个设备类型,如果要实现不同的独立功能模块,并且相对独立,以及具有单独的入口的功能特性,建议做成一个独立特性的 HAP,按需下载安装。

组成结构:
此时一个 App 包中,就会有多个 HAP 包,其中有且仅有一个 Entry 类型的 HAP,其他的均是 Feature 类型的 HAP。多 HAP 之间业务独立,但是可能会有业务能力共享,所以在进行模块化设计时,需要根据是否具有公共能力来进行选择。

🔥 面试要点 1:包含公共能力模块

面试官:多 HAP 工程如何处理公共能力模块?

对于具备公共能力模块的工程,和上述 HAP+HSP 组合是类似的,需要考虑在 App Size 与启动性能之间做平衡。

性能优先方案:

图 9 多 HAP 工程模块示意图
多HAP工程模块

特点:
一般多 HAP 应用架构普适性采用以下模型,除了产品组件中存在 HAP 包之外,其余的均是 HAR 包。

编译产物中,多个 HAP 之间存在相同的 HAR 包(如 har_2、har_3、har_C、har_D、har_E)。这种情况下,App Size 可能会增大。如果 App Size 不是应用的瓶颈,或者 HAR 包的大小较小,对 App Size 的影响可控,可以采用这种模型,从而减少动态加载的性能损耗。

App Size 优先方案:

图 10 多 HAP 工程模块示意图
App Size优先方案

设计思路:
上述问题的本质在于如何在 HAP 和 HSP 之间分布 HAR 包,以最小化 App 的大小并减少 HAR 的重复编译和打包。主要思路是将公共能力模块封装为公共 HSP,从而最小化 App Size。

⚠️ 重要注意事项:
需要注意,在应用间共享的 HAR 包,原则上是不允许依赖 HSP 包,因为 HSP 包是专属于应用,和 bundleName 进行了绑定,一旦 HAR 包依赖于应用内 HSP,该 HAR 包就丢失了共享性,无法再给其他应用共享。

实现方案:
如上图所示,有 3 个 HAP 包(1 个 entry 和 2 个 feature),将公共的 HAR 包封装到 HSP 工程中,例如 common_wrap_hsp 和 feature_wrap_hsp。

// 模块壳设计示例
// common_wrap_hsp 和 feature_wrap_hsp 仅为模块壳
// 用于合理放置模块在编译产物中的位置
// 不具备模块功能,不能共享,仅能在 App 应用内使用

这两个 HSP 从严格意义上讲,不能称为模块,仅称为模块壳,用于合理放置模块在编译产物中的位置,不具备模块功能,不能共享,仅能在 App 应用内使用,依赖这些模块壳的模块也无法在应用间共享。

上述的模型通过 HSP 将 HAR 包合理分配到编译产物中,确保每个 HAR 包在 App 编译产物中仅出现一次,从而减小 App Size。模块壳数量不宜过多,否则可能影响安装速度和启动性能。

平衡方案:
这两种模型都是理想模型,业务模型通常是两者的平衡态或组合。例如,某个共享库代码和资源较少,占用空间较小,如打印日志模块。将该模块编译进所有编译产物中,App Size 增加较少,同时性能较好。

🔥 面试要点 2:不包含公共能力模块

回答要点:
这种应用较少,即使有的话也是一些规模较小的应用,可以参考单 HAP 的场景。


🚀 面试总结:模块化设计决策树

📊 决策流程图

应用模块化设计
├── 是否需要独立运行和安装?
│   ├── 是 → Feature HAP
│   └── 否 → 继续判断
├── 是否需要按需加载?
│   ├── 是 → HSP
│   └── 否 → 继续判断
├── 是否需要跨应用共享?
│   ├── 是 → HAR (通过 OHPM 仓)
│   └── 否 → HAR (应用内使用)
└── 性能 vs App Size 权衡├── 性能优先 → HAR└── App Size 优先 → HSP 模块壳

🎯 面试记忆口诀

“独立运行选 HAP,按需加载用 HSP,跨应用共享靠 HAR”

  • HAP:独立 Ability,独立安装
  • HSP:动态共享,按需加载
  • HAR:静态共享,编译打包

💪 面试优势回答模板

面试官:如何选择合适的模块化方案?

完美回答:

应用开发者需根据技术架构选择适合的工程模块化模型。工程模块化模型需根据业务和技术架构演进而演进。根据诉求在 HAP、HAR 和 HSP 中选择使用。

具体选择标准:

  1. 独立运行和安装的模块:只能选择 HAP 包,并将其作为 Feature 类型的 HAP 存在于 App 中
  2. 按需加载模块:对于不具备独立特性部分,用户使用频率较少的模块,将其做成 HSP 按需加载模块存在于 App 中
  3. 共享模块:对于需要共享的模块,只能采用 HAR 包,将其通过 OHPM 仓共享给其他工程使用
  4. 性能优化:HAR 是静态共享库,在多 HAP 或者按需加载场景下,在编译后可能会在物理上存在多份,所以需要合理采用公共 HSP 模块壳,使 App Size 最小化

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

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

相关文章

Maven高级学习笔记

分模块设计 为什么分模块设计?将项目按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享。 注意事项:分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕&…

[创业之路-423]:经济学 - 大国竞争格局下的多维博弈与科技核心地位

在当今风云变幻的国际舞台上,大国竞争已成为时代的主旋律,其激烈程度与复杂性远超以往。这场全方位的较量,涵盖了制度、思想、文化、经济、科技、军事等诸多关键领域,每一个维度都深刻影响着大国的兴衰成败,而科技在其…

【企业容灾灾备系统规划】

一、企业灾备体系 1.1 灾备体系 灾备切换的困境: 容灾领域的标准化方法和流程、算法体系是确保业务连续性和数据可靠性的核心,以下从标准框架、流程规范、算法体系三个维度进行系统分析: 1.1.1、标准化方法体系​ ​1. 容灾等级标准​ ​国际标准SHARE78​: 将容灾能力划…

Kafka Connect基础入门与核心概念

一、Kafka Connect是什么? Apache Kafka Connect是Kafka生态中用于构建可扩展、可靠的数据集成管道的组件,它允许用户将数据从外部系统(如数据库、文件系统、API等)导入Kafka(Source Connector)&#xff0…

从零手写Java版本的LSM Tree (四):SSTable 磁盘存储

🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…

Kotlin的5个主要作用域函数

applay, also,let, run, with 是kotlin标准库提供的5个主要的作用域函数(Scope Functions)​,它们的设计目的是为了在特定作用域内更简洁地操作对象。 如何使用这5个函数,要从它的设计目的来区分: apply : 配置/对象…

原型模式Prototype Pattern

模式定义 用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象,其允许一个对象再创建 另外一个可定制的对象,无须知道任何创建的细节 对象创建型模式 基本工作原理是通过将一个原型对象传给那个要发动创建的对象,这…

基于深度学习的智能交通流量预测系统:技术与实践

前言 随着城市化进程的加速,交通拥堵问题日益严重,给人们的日常生活和经济发展带来了巨大的挑战。智能交通系统(ITS)作为解决交通问题的重要手段,逐渐成为研究的热点。其中,交通流量预测是智能交通系统中的…

Cilium动手实验室: 精通之旅---23.Advanced Gateway API Use Cases

Cilium动手实验室: 精通之旅---23.Advanced Gateway API Use Cases 1. Lab说明1.1 高级网关 API 使用案例 2. 负载均衡器2.1 部署应用程序2.2 部署 Gateway 和 HTTPRoute 3. HTTP 标头请求修饰符3.1 部署 HTTPRoute3.2 可观测性 4. HTTP 响应标头重写5. HTTP 流量镜像5.1 demo应…

Agentic Workflow是什么?Agentic Workflow会成为下一个AI风口吗?

无论是想要学习人工智能当做主业营收,还是像我一样作为开发工程师但依然要运用这个颠覆开发的时代宠儿,都有必要了解、学习一下人工智能。 近期发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,入行门槛低&#x…

Some chunks are larger than 500 KiB after minification. Consider

在 vue3vite 项目开发中,build 打包时出现以下警告报错: (!) Some chunks are larger than 500 KiB after minification. Consider: - Using dynamic import() to code-split the application - Use build.rollupOptions.output.manualChunks to improve…

NodeJS11和10以及之前的版本,关键差异?

Node.js 11 相比 10(及更早版本),除了事件循环行为的重大改变,还有多个核心模块和底层机制的升级。以下是它们的关键差异和新特性对比,帮助你快速掌握两个版本的重要变化。 🔧 一、事件循环行为变化&#x…

调和级数 敛散性

调和级数的敛散性是一个非常经典的问题。我们来全面分析它。 🧠 调和级数定义 调和级数是指: ∑ n 1 ∞ 1 n 1 1 2 1 3 1 4 ⋯ \sum_{n1}^{\infty} \frac{1}{n} 1 \frac{1}{2} \frac{1}{3} \frac{1}{4} \cdots n1∑∞​n1​121​31​41​⋯ …

Python•元组集合字符串

ʕ⸝⸝⸝˙Ⱉ˙ʔ ♡ 元组🛥️创建访问修改解包其他操作比较的依据 集合🛸创建添加和删除其他操作 字符串🪂创建索引和切片基本操作连接加号join() 重复查找in 关键字index()find()startswith()endswith() ​​替换​​分割​​大小写删除 能…

​​信息系统项目管理师-项目整合管理 知识点总结与例题分析​​

​​一、项目整合管理概述​​ ​​1. 定义与重要性​​ 项目整合管理是项目管理知识领域中的核心过程,它协调所有其他知识领域的过程和活动,确保项目各要素有效整合。其核心目标是: ​​统一项目目标​​:确保各要素服务于共同目标​​协调冲突​​:解决项目执行中的各…

『uniapp』onThemeChange监听主题样式,动态主题不正确生效,样式被覆盖的坑

目录 问题示例代码解决思路1(缺点影响显示效果有延迟)解决思路2——通过路由刷新页面(缺点只适用于部分网页)解决思路3——vuex(没学会~)总结 欢迎关注 『uniapp』 专栏,持续更新中 欢迎关注 『…

LeetCode 高频 SQL 50 题(基础版)【题解】合集

点击下方标题可跳转至对应部分: LeetCode 高频 SQL 50 题(基础版)之 【查询】部分 LeetCode 高频 SQL 50 题(基础版)之 【连接】部分 上 LeetCode 高频 SQL 50 题(基础版)之 【连接】部分 下…

Jenkins 全面深入学习目录

Jenkins 全面深入学习目录 第一部分:Jenkins 基础入门 Jenkins 概述 持续集成/持续交付(CI/CD)概念Jenkins 的历史与发展Jenkins 与其他 CI/CD 工具的比较 Jenkins 安装与配置 系统要求与环境准备不同操作系统下的安装方法初始配置与安全设置插件管理系统 Jenkins…

安装laravel11和laravel12的一些报错问题解决

前言 今天在安装laravel的过程中遇到一些报错问题,记录一下。 laravel 12 Root composer.json requires laravel/tinker ^2.10.1, found laravel/tinker[2.x-dev] but it does not match your minimum-stability laravel/framework[v12.0.0, ..., v12.15.0] requ…

Oracle21cR3之客户端安装错误及处理方法

文章目录 Oracle21cR3客户端安装1. 下载2. 安装解压到指定位置,如下:2. 安装 3. 常见错误1. 无法将 JINSHENGYUAN\jinshengyuan 安装用户添加到 %2% 组。1. 问题原因分析2. 处理方法 Oracle21cR3客户端安装 1. 下载 官网下载 2. 安装 解压到指定位置…