一、详细知识点1. UIAbilityUIAbility是带 UI 的应用组件负责生命周期入口。常见回调包括创建、窗口创建、前台、后台和销毁。exportdefaultclassEntryAbilityextendsUIAbility{onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.loadContent(pages/Index)}}2. WindowStageWindowStage负责窗口管理和页面加载。首页路径错、资源错或页面构建异常都可能表现为启动失败或白屏。3. ContextContext是访问资源、文件、系统能力和运行环境的重要入口。工程化开发要明确 Context 生命周期不要把短生命周期对象长期持有。4. 页面导航简单 demo 可用页面状态切换生产项目应使用官方推荐导航能力组织页面栈、参数和返回行为。无论哪种方式都要处理参数缺失和数据不存在。5. 权限与系统能力调用网络、位置、媒体、通知等能力时要先声明权限再按场景申请或检查。用户拒绝权限是正常路径必须给替代方案。6. 数据架构Page 页面Component 组件Service 业务服务Remote API / Mock APILocal Store / PreferencesModel 类型模型工程要求Page 只做展示和交互。Service 负责业务编排。Store 负责本地状态和持久化。Remote API 负责网络请求。Model 做边界转换避免脏数据进入 UI。二、本章 demoDemo 1生命周期日志EntryAbility.ets中记录生命周期onForeground():void{hilog.info(0x0000,HarmonyNews,onForeground)}onBackground():void{hilog.info(0x0000,HarmonyNews,onBackground)}Demo 2收藏状态封装FavoriteStore.etsstatictoggle(articleId:string):void{if(FavoriteStore.favoriteIds.has(articleId)){FavoriteStore.favoriteIds.delete(articleId)}else{FavoriteStore.favoriteIds.add(articleId)}}Demo 3页面只调用服务Index.ets不直接维护收藏集合而是调用FavoriteStore.toggle()和NewsService.markFavorites()保持页面薄。三、面试题与详细答案1.UIAbility和页面是什么关系UIAbility是应用组件入口负责生命周期和窗口创建页面是 ArkUI 渲染内容。UIAbility通过WindowStage.loadContent()加载页面。页面不应该承担应用生命周期管理职责。2. 为什么不能在生命周期里做重任务生命周期回调影响启动和前后台切换如果做长时间同步任务会造成首屏慢、卡顿甚至 ANR 风险。重任务应拆到异步流程首屏只做必要初始化。3. 权限拒绝时应该怎么处理权限拒绝是用户选择不是程序异常。应用应解释原因、提供降级能力、允许稍后再开启而不是直接崩溃或强制退出。4. Repository / Service 分层解决什么问题它把页面和数据源解耦。页面不关心数据来自网络、缓存还是 mock测试时可以替换 Service接口变更时集中修改转换逻辑。这是从 demo 走向生产工程的关键。四、五倍扩展知识点矩阵1. Stage 模型对象关系对象职责常见使用工程风险UIAbilityUI 应用组件入口生命周期、窗口创建生命周期阻塞WindowStage窗口舞台加载页面页面路径和窗口状态错误Context上下文资源、文件、系统能力错误持有导致泄漏Want启动参数跨 Ability 传参参数缺失和类型不匹配AbilityStageHAP 级初始化模块启动逻辑初始化过重ExtensionAbility扩展能力卡片、服务等生命周期和权限差异module.json5模块声明Ability、权限配置与代码不一致app.json5应用身份包名、版本发布后变更风险resources资源字符串、颜色、媒体多语言和主题治理hilog日志生命周期和错误敏感信息泄露2. 生命周期实践回调适合做不适合做onCreate轻量初始化、日志网络大请求、重 IOonWindowStageCreate加载首页、窗口配置业务批处理onForeground恢复监听、刷新短期状态重复创建资源onBackground保存草稿、暂停任务开启新长任务onDestroy清理资源发起不可控异步生产实践理解生命周期不是业务万能入口。它是应用运行状态变化的边界业务初始化要分级首屏必要、首屏后、用户触发、后台可延迟。3. 权限治理权限场景产品问题技术问题合规问题网络为什么需要联网失败和超时数据传输说明位置是否必须精准定位授权拒绝降级高敏感信息相机是否必须拍摄设备无能力用户授权说明相册是否可替代文件格式最小访问范围通知是否打扰用户通知开关用户可关闭麦克风是否必要录音失败明确用途文件保存在哪里空间不足数据删除后台任务是否真需要耗电用户感知4. 数据架构扩展Page / ComponentView StateService / UseCaseRepositoryRemote APILocal StoreDTO MapperError Mapping分层解释Page 只关心展示状态。View State 组合 loading、error、data。Service 表达业务动作如刷新、收藏、保存设置。Repository 屏蔽远程和本地数据源。Mapper 处理 DTO 到领域模型。Error Mapping 把底层错误变成用户可理解状态。5. 缓存策略策略适合场景风险只读远程实时性强弱网体验差先缓存后网络新闻、配置数据可能短暂旧只本地设置、草稿多端同步差写穿缓存写后马上读写失败处理复杂定时刷新首页推荐耗电和流量用户触发刷新列表页用户等待分页缓存长列表缓存清理版本化缓存数据结构升级迁移成本五、系统能力 demo 扩展任务任务目标验证增加网络权限说明学会权限声明module.json5有权限模拟 HTTP 失败学会错误状态页面显示重试增加缓存读取学会本地优先首屏先显示旧数据增加设置持久化学会 Preferences 思路重启后保留设置增加权限拒绝文案学会降级用户知道原因增加详情参数校验防止空参数缺 id 显示空状态增加刷新节流防重复请求连点不重复发起增加 Repository解耦页面和数据源Page 不知道 mock增加错误码映射技术错误转业务错误页面文案清晰增加日志 traceId排查链路日志能串起来扩展示例Repository 接口exportinterfaceNewsRepository{queryArticles():PromiseNewsArticle[]queryArticleById(id:string):PromiseNewsArticle|undefinedtoggleFavorite(id:string):Promisevoid}接口化后页面可以依赖抽象测试时使用 FakeRepository生产时使用 RemoteRepository LocalStore。六、数据流检查检查项好的表现坏的表现数据来源页面知道状态不知道接口细节页面直接拼接口错误处理分技术错误和用户文案catch后静默缓存有版本和失效策略永久保存不清理权限拒绝可降级拒绝就崩溃日志有模块和动作只有 error安全不记录敏感信息token 写日志测试Service 可替换只能真机点并发处理重复请求状态互相覆盖恢复前后台状态合理返回页面错乱扩展新数据源容易接页面大改七、扩展面试题5. Stage 模型里为什么要区分 Ability 生命周期和页面生命周期Ability 生命周期描述应用组件的运行状态页面生命周期描述 UI 组件的出现和消失。二者粒度不同。把页面数据加载都塞进 Ability 会让入口过重把应用级资源管理放进页面又会导致重复初始化。6. 权限最小化如何落地先从业务需求反推权限能不用就不用能低敏就不用高敏。配置文件只声明真实需要的权限运行时在用户触发相关功能时申请并提供拒绝后的降级路径。上线前检查权限说明和实际使用是否一致。7. Repository 和 Store 的区别是什么Repository 负责统一数据访问可以组合远程、本地和转换逻辑Store 更偏本地状态或持久化状态管理。Repository 可以使用 Store但页面最好通过 Service 或 Repository 获取业务数据。8. 如何设计弱网体验首屏尽量展示缓存请求要有超时失败要有重试关键操作要有明确状态不要无限转圈。对于写操作要说明是否成功、是否可重试、是否会重复提交。9. Context 为什么不能随意长期持有Context 和运行环境、Ability 生命周期有关。随意长期持有可能造成生命周期错乱或资源无法释放。需要系统能力时应在合适作用域获取并避免把短生命周期对象保存到全局单例中。10. 如何从 demo 架构演进到生产架构先把 mock 数据移入 Service再抽 Repository再增加 LocalStore 和 RemoteAPI再统一错误处理和日志最后补测试和发布检查。每一步都保持页面调用方式稳定避免 UI 随数据源变化大改。八、Stage 与数据架构详解库1. 生命周期是资源管理边界前后台切换、窗口创建和销毁决定了资源何时创建、暂停、恢复和释放。网络轮询、动画、定位、监听器等都要和生命周期绑定否则会带来耗电、内存和状态问题。2. 首屏初始化要分级首屏必要任务包括加载首页、读取最低限度设置、准备关键 UI。非必要任务如预加载推荐、同步历史、上传日志应延后。启动阶段越重用户感知越差。3. Want 参数必须校验跨 Ability 或页面传参时参数可能缺失、类型不对或来自旧版本。详情页根据 id 加载数据时必须处理 id 为空和文章不存在。4. 权限申请要绑定用户动作应用启动就申请大量权限体验很差。更好的方式是在用户触发相关功能时说明原因并申请。拒绝后提供降级路径。5. Repository 是数据源防火墙页面不应该知道数据来自 mock、HTTP、缓存还是数据库。Repository 隐藏这些细节让页面只处理业务状态。6. 本地缓存要有失效策略缓存不是永久保存。新闻列表可以设置时间失效用户设置可以长期保存登录态和敏感信息要按安全策略管理。7. 弱网不是异常边角移动应用大量场景都可能弱网。架构要内置超时、重试、缓存、错误提示和重复提交保护。8. 日志要串联链路一次用户操作可能经过 Page、Service、Repository、Remote 和 Store。日志如果没有 traceId 或上下文很难定位问题发生在哪一层。9. 多设备能力要先抽象不同设备能力不同页面不应直接假设所有系统能力都可用。要有能力检测、降级和设备差异策略。10. 架构演进要小步保持可运行不要一次性把 demo 重构成复杂架构。每次只引入一个边界先 Service再 Store再 Repository再 Remote。每一步都保持项目可运行。九、Stage 与系统能力场景库场景架构动作风险验收启动首页Ability 加载页面白屏首页显示前台恢复刷新短状态重复请求日志清楚后台切换保存草稿数据丢失返回恢复打开详情校验 id空参数空状态请求新闻Service 调 Repository网络失败重试收藏文章Store 更新状态不同步列表和收藏页一致设置主题Store 持久化重启丢失重新打开保留权限拒绝降级提示崩溃用户可返回缓存过期重新拉取旧数据有刷新策略弱网超时错误映射无限加载出现提示多设备能力检测调用失败降级可用日志追踪traceId无法定位链路可串十、扩展面试题库11. 为什么首屏不应该等待所有接口用户首先需要看到可交互界面。等待所有接口会放大最慢接口的影响。应优先加载首屏必要数据非关键数据延后或并发加载。12. 如何设计缓存失效根据数据性质决定。新闻列表可以短时间缓存并允许手动刷新用户设置长期有效敏感数据要有安全和清理策略。缓存要记录版本和时间避免旧结构解析失败。13. 弱网下如何避免重复提交按钮点击后进入提交中状态禁用重复点击请求带业务幂等标识失败时明确是否可重试重试不能造成重复业务结果。14. 为什么权限弹窗要延后到具体场景用户在具体场景下更容易理解权限用途。启动即申请会让用户困惑也可能导致拒绝率上升。延后申请还能减少不必要权限。15. 如何判断架构是否过度设计如果抽象没有减少重复、没有隔离变化、没有提升测试性只是增加文件和跳转就是过度设计。架构应服务当前复杂度并允许未来平滑扩展。十一、系统能力知识体系补全能力域关键能力封装建议验收点应用框架UIAbility、ExtensionAbility、Want、ContextAbilityService生命周期日志完整导航与启动router、Navigation、深链、Want 参数NavigationService参数缺失可恢复权限声明、申请、拒绝、撤回PermissionService拒绝不崩溃网络HTTP、超时、重试、弱网HttpClient失败有错误映射数据存储Preferences、文件、relationalStoreLocalDataSource缓存可读写媒体图片、相册、音视频、拍摄MediaService授权和失败处理通知通知权限、频道、点击跳转NotificationService可开启可关闭后台任务短任务、延迟任务、WorkScheduler 类场景BackgroundTaskService不滥用后台并发taskpool、worker、异步队列TaskServiceUI 不阻塞设备能力窗口、屏幕、设备类型、传感器DeviceService多设备可降级卡片FormExtensionAbility、卡片数据刷新WidgetService卡片独立可用分布式/协同多设备流转、数据协同场景CollaborationService状态迁移清楚日志hilog、traceId、分级Logger日志可串联十二、数据架构分层方案Page / ComponentViewStateUseCase / ServiceRepository InterfaceRemoteDataSourceLocalDataSourceMemoryCacheDTOMapperDomain ModelErrorMapper职责说明ViewState描述页面状态不直接描述网络细节。UseCase表达业务动作如刷新新闻、收藏文章、保存设置。Repository屏蔽数据源页面不关心远程还是本地。RemoteDataSource只负责请求和响应 DTO。LocalDataSource负责 Preferences、文件或数据库。Mapper把 DTO 转成领域模型。ErrorMapper把系统错误转成业务错误。十三、持久化选型数据推荐方式原因注意主题、字号Preferences小数据、读取快版本迁移收藏 idPreferences 或数据库数据简单数量增长时迁移新闻缓存文件或数据库数据较多失效策略阅读历史数据库可查询、可分页清理策略草稿文件/数据库需要恢复防损坏登录态安全存储能力敏感不能明文图片缓存文件缓存体积大容量上限配置Preferences 远程配置快速读取灰度生效十四、并发与后台任务场景推荐策略风险首页并行加载并发请求错误聚合图片处理worker/taskpool线程通信成本大列表计算后台计算 分批更新旧任务覆盖新任务定时刷新按需触发耗电日志上传延迟或批量隐私和流量离线同步队列重复提交搜索防抖延迟触发响应延迟并发设计要先保证正确性再考虑速度。所有后台结果回到 UI 前都要校验页面是否仍需要该结果。十五、架构设计文档模板1. 业务目标 2. 页面范围 3. 模块划分 4. 数据模型 5. 状态流 6. 网络和缓存策略 7. 权限和系统能力 8. 错误处理 9. 性能风险 10. 安全和隐私 11. 测试方案 12. 发布和回滚项目达到一定规模后每个核心功能都应有轻量设计文档。没有设计文档后续维护只能靠读代码猜意图。十六、架构练习套件练习目标验收抽 Repository页面不关心数据源可切换 mock/remote加 Preferences设置持久化重启保留加数据库设计阅读历史分页可查询可删除加权限服务统一申请拒绝可降级加通知服务收藏更新提醒可关闭加后台队列日志批量上传不阻塞 UI加错误映射系统错误转业务文案文案统一加 traceId请求链路追踪日志可关联加模块边界feature/common 分层依赖方向正确加架构图说明系统结构新人能读懂十七、补充面试题16. 如何给鸿蒙应用设计数据层先定义领域模型再定义 Repository 接口然后实现 RemoteDataSource、LocalDataSource 和 Mapper。页面只依赖业务服务不直接接触 HTTP、Preferences 或数据库。17. Preferences 和数据库如何选择Preferences 适合少量 key-value 数据如设置和轻量状态数据库适合结构化、可查询、可分页的数据如阅读历史、离线列表。选择时看数据量、查询方式、更新频率和迁移成本。18. 系统能力为什么要统一封装权限、通知、媒体、文件等系统能力都有失败路径和设备差异。统一封装可以集中处理权限、日志、错误映射和降级避免页面到处散落系统 API。19. 如何设计模块依赖方向业务 feature 可以依赖 common-ui、common-model、common-data但 common 不能反向依赖 feature。数据层不能依赖 UI。依赖方向越单向项目越容易扩展和测试。20. 架构设计如何避免空谈每个架构结论都要落到文件结构、接口定义、数据流、错误处理和测试方式。只画图不落代码约束就不能指导开发。