Harmony面试模版

1. 自我介绍

看表达能力、沟通能力

面试记录:

2. 进一步挖掘

2.1. 现状

目前是在职还是离职,如果离职,从上一家公司离职的原因

2.2. 项目经验

如果自我介绍工作项目经验讲的不够清楚,可以根据简历上的信息再进一步了解

面试记录:

3. 鸿蒙技术问题

3.1. ArkTS
3.1.1. 基础
3.1.1.1. 基本数据类型有哪些

|------|-----------|----------------------------------------------------------------------------------------|
| | 数据类型 | 概述 |
| 基本类型 | number | 数值 |
| 基本类型 | boolean | 布尔 |
| 基本类型 | string | 字符串 |
| | array | |
| | Record | |
| | Object | Object类型是所有引用类型的基类型。任何值,包括基本类型的值(它们会被自动装箱),都可以直接被赋给Object类型的变量。 |
| | object | object类型则用于表示除非基本类型外的类型。 |
| | enum | 枚举 |
| | Union | union类型,即联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。 typeAnimal = Cat | Dog | Frog | number; |
| | undefined | 一个未定义或不存在的值 |
| | null | 空 |
| | object | 对象 |
| | Symbol | 独一无二的值 |
| | bigint | 任意大的整数 |
| | any | 任意 |
| | unknown | 未知类型 |
| | void | 没有任何返回值的类型 |
| | never | 永远不存在的类型 |
| | NaN | parseInt一个非数字字符串,不会走到catch,会直接返回一个NaN |

不用讲全,可以引导讲一下常用的用法和注意事项

延伸问题

  • 如Map不能转json,要用Record
  • 枚举比较运算符需要用"===",否则不会返回true
  • if条件中,数值类型0会返回false
3.1.1.2. let 和 const区别

|----|----------------------|---------|
| 区别 | let | const |
| 类型 | 声明变量 | 声明常量 |
| 赋值 | 可以被多次赋值,最后一次赋值覆盖前面的值 | 只能被赋值1次 |

3.2. 并发

文档中心

为了提升应用的响应速度与帧率,避免耗时任务对UI主线程的影响,ArkTS提供了异步并发和多线程并发两种处理策略。

  • 异步并发是指异步代码在执行到一定程度后会被暂停,以便在未来某个时间点继续执行,这种情况下,同一时间只有一段代码在执行。ArkTS通过Promise和async/await提供异步并发能力,适用于单次I/O任务的开发场景。详细请参见使用异步并发能力
  • 多线程并发允许在同一时间段内同时执行多段代码。在UI主线程继续响应用户操作和更新UI的同时,后台线程也能执行耗时操作,从而避免应用出现卡顿。ArkTS通过TaskPool和Worker提供多线程并发能力,适用于耗时任务等并发场景。详细请参见多线程并发概述
3.2.1. 异步并发

Promise async/await

使用场景

用法简单描述

对于异步并发的理解:不开启新线程

3.2.2. 多线程并发
3.2.2.1. TaskPoll和Worker的区别?

TaskPool和Worker均支持多线程并发能力。由于TaskPool的工作线程会绑定系统的调度优先级,并且支持负载均衡(自动扩缩容),而Worker需要开发者自行创建,存在创建耗时以及不支持设置调度优先级,故在性能方面使用TaskPool会优于Worker,因此大多数场景推荐使用TaskPool。

TaskPool偏向独立任务维度,该任务在线程中执行,无需关注线程的生命周期,超长任务(大于3分钟且非长时任务)会被系统自动回收;而Worker偏向线程的维度,支持长时间占据线程执行,需要主动管理线程生命周期。

延伸问题

TaskPool线程间通信,假如传递的是一个对象,这个对象的父类属性和方法在另外一个线程能调用到吗?

答案:调用不到,因为线程间传递对象是,把对象序列化了,序列化再反序列化后,父类的属性和方法就丢失了。

3.2.3. 数据持久化

HarmonyOS标准系统支持典型的存储数据形态,包括用户首选项、键值型数据库、关系型数据库。

开发者可以根据如下功能介绍,选择合适的数据形态以满足自己应用数据的持久化需要。

  • 用户首选项(Preferences):通常用于保存应用的配置信息。数据通过文本的形式保存在设备中,应用使用过程中会将文本中的数据全量加载到内存中,所以访问速度快、效率高,但不适合需要存储大量数据的场景。
  • 键值型数据库(KV-Store):一种非关系型数据库,其数据以"键值"对的形式进行组织、索引和存储,其中"键"作为唯一标识符。适合很少数据关系和业务关系的业务数据存储,同时因其在分布式场景中降低了解决数据库版本兼容问题的复杂度,和数据同步过程中冲突解决的复杂度而被广泛使用。相比于关系型数据库,更容易做到跨设备跨版本兼容。
  • 关系型数据库(RelationalStore):一种关系型数据库,以行和列的形式存储数据,广泛用于应用中的关系型数据的处理,包括一系列的增、删、改、查等接口,开发者也可以运行自己定义的SQL语句来满足复杂业务场景的需要。
3.3. ArkUI
3.3.1. ArkUI框架有哪些特点?

ArkUI框架是鸿蒙(HarmonyOS)中的一个重要组件框架,具有以下几个特点:

  1. 组件树结构 : ArkUI框架通过布局组件和基础组件构建界面描述树(组件树),其中基础组件为叶子节点,布局组件为中间节点 。当用户进行交互时,会触发界面修改,通过重新渲染组件树来实现应用界面更新 。
  2. 数据与UI更新过程 : ArkUI框架的数据处理过程和UI更新过程是分开进行的。数据处理过程中,主要是对状态数据进行更新,并通过标脏过程确定布局最小影响范围,减少不必要的重新布局 。UI更新过程包括组件标脏、布局、测量和渲染等阶段 。
  3. 布局组件 : ArkUI框架提供了多种布局组件,如Row、Column、Stack、Flex、List、Grid、RelativeContainer等。开发者可以根据场景选择合适的布局组件,以优化性能 。例如,线性布局(Row、Column)适用于横向或纵向排列组件,而弹性布局(Flex)适用于需要弹性排列的场景。
  4. 性能优化 : ArkUI框架在性能优化方面做了很多工作。例如,通过减少不必要的组件嵌套和节点数量,降低布局测算的复杂度,从而提升性能。开发者可以使用DevEco Studio提供的工具(如Profiler和ArkUI Inspector)来查看性能瓶颈和组件树结构,进一步优化应用性能。
  5. 状态管理 : ArkUI框架支持状态管理最佳实践,通过有效的状态管理减少无效的UI更新操作,提升性能。例如,在状态变量变化导致UI更新时,只更新部分组件,而不是重新渲染整个界面。
3.3.2. 生命周期
3.3.2.1. UIAbility生命周期、启动流程
3.3.2.2. Page和自定义组件生命周期

有@Entry装饰器的@component组件的生命周期

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
  • onBackPress:当用户点击返回按钮时触发。

有@Entry装饰器和无@Entry装饰器@Component组件都有的生命周期

  • aboutToAppear :组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其 build()函数之前执行。
  • onDidBuild :API12新增,组件 build()函数执行完成之后回调该接口,不建议在 onDidBuild函数中更改状态变量、使用 animateTo等功能,这会导致不稳定的UI表现。
  • aboutToDisappearaboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改会导致应用程序行为不稳定。

说一下顺序

页面又刷新,会走aboutToAppear吗

组件尺寸变化回调

abouttodisappear不适合异步,阻碍回收

3.3.3. 手势优先级的运用

两个手势冲突,怎么处理

3.3.4. ArkUI状态管理

V1

@State @Prop @Link @ObjectLink

@Provide/@Consume

@Builder 和 @BuilderParam

@Watch 监视数据的变化(第一次不会触发)

@State @Prop @Link哪个性能最差

文档中心

V2

@ObserveV2 @Trace

3.3.4.1. 如何进行全局状态管理?

应用全局的UI状态存储

  1. @Provide+@Consume装饰器 适用场景:适用于整个组件树而言"全局"的状态共享,且该状态改动不频繁的场景。 工作原理:通过在最顶层组件中使用 @Provide装饰器提供状态,其他需要共享状态的组件通过 @Consume装饰器获取该状态 。 优点:减少了状态传递的层级,提升了代码的可维护性和可拓展性。 注意事项:确保状态的生命周期与组件树的生命周期一致,避免不必要的UI刷新。
  2. AppStorage 适用场景:适用于整个应用而言"全局"的变量或应用的主线程内多个 UIAbility实例间的状态共享。 工作原理:AppStorage与应用的进程绑定,由UI框架在应用程序启动时创建,当应用进程终止,AppStorage被回收。 优点:适用于需要在整个应用中共享状态的场景。 注意事项:确保状态的生命周期与应用进程一致,避免在应用退出后仍有状态存在。
  3. LocalStorage 适用场景:适用于单个Ability而言"全局"的变量,主要用于不同页面间的状态共享。 工作原理:LocalStorage的生命周期由应用程序决定,当应用释放最后一个指向 LocalStorage的引用时,LocalStorage被垃圾回收。 优点:适用于需要在单个UIAbility中不同页面间共享状态的场景。 注意事项:确保状态的生命周期与应用程序的生命周期一致,避免在应用退出后仍有状态存在。
3.3.4.2. LocalStorage在应用重启后数据会消失吗?

页面级UI状态存储

会,因为LocalStorage 是一种用于页面或组件级别的数据存储方式,它允许开发者在页面或组件的生命周期内存储和检索数据。LocalStorage 的数据存储在内存中,因此它的读写速度相对较快。但是,当应用重启后,LocalStorage 中的数据会丢失。

3.3.4.3. @Provider和@Consumer vs @Provide和@Consume的区别

|----------|------------------------------------------------------|-------------------------------------------------------|
| | @Provider和@Consumer | @Provide和@Consume |
| 版本历史 | V2 | V1 |
| 是否本地初始化 | 允许本地初始化,当找不到@Provider 的时候使用本地默认值 | 禁止本地初始化,当找不到对应的@Provide 时候,会抛出异常。 |
| 支持类型 | 支持 function。 | 不支持 function。 |
| 观察能力 | 仅能观察自身赋值变化,如果要观察嵌套场景,配合@Trace 一起使用 | 观察第一层变化,如果要观察嵌套场景,配合@Observed 和@ObjectLink 一起使用。 |
| 命名 | alias 和属性名alias 是唯一匹配的 key,如果缺省 alias,则默认属性名为 alias。 | alias 和属性名都为 key,优先匹配 alias,匹配不到可以匹配属性名。 |
| 从父组件初始化 | 允许 | 禁止 |
| 支持重载默认开启 | 即@Provider 可以重名,@Consumer 向上查找最近的@Provider。 | 默认关闭,即在组件树上不允许有同名@Provide。如果需要重载,则需要配置 allowOverride。 |

3.3.5. ForEach和LazyForEach的区别?

ForEach和LazyForEach都是用于渲染列表的装饰器,它们的区别在于:

ForEach:渲染列表时,会将列表中的每一项都渲染一次,适用于列表项数量较少的情况。

LazyForEach:渲染列表时,只渲染当前可见的列表项,适用于列表项数量较多的情况。

3.3.6. ArkUI动画

文档中心

3.3.7. 上拉加载和下拉刷新如何实现?

上拉加载: 使用pullToRefresh组件可以实现上拉加载更多数据的效果 。该组件支持懒加载,可以通过设置LazyForEach来实现数据的按需加载 。 在使用pullToRefresh组件时,需要将列表组件、绑定的数据对象和scroller对象包含进去,并添加上滑方法。

下拉刷新: 可以使用Refresh组件来实现下拉刷新功能 。刷新逻辑可以在onRefreshing回调方法中执行。 当列表滑动到底部时,可以触发onReachEnd事件回调,用于加载更多数据 。 这些组件和方法可以帮助开发者在鸿蒙(HarmonyOS)中实现流畅的上拉加载和下拉刷新功能,提升用户体验。

4. 进阶问题

4.1. 鸿蒙动态UI加载

文档中心

4.2. 如何优化应用的性能?
  • 内存管理:合理分配和释放内存,避免内存泄漏。(按需分配(懒加载),及时释放)
    • 如避免循环依赖
    • 组件内生命周期的大内存对象在aboutToDisappear手动销毁释放
    • 播放器资源如果不需要在屏幕渲染了,及时释放
  • 后台优化:合理使用后台服务和定时任务,避免不必要的后台运行。
  • UI渲染优化
    • 使用轻量级的UI组件,减少布局复杂度,优化渲染性能。
    • 图片压缩
    • 图片/视频资源预加载
  • 资源优化
    • 压缩图片和媒体资源,减少应用的体积和加载时间。
    • 耗时的绘制换成图片
  • List等列表组件
    • LazyForEach,合理使用cachedCount
    • 复用
  • 耗时任务放到异步线程(不卡主线程)
4.3. H5如何与HarmonyOS应用(webView)进行通信?官方文档

应用侧可以通过runJavaScript()方法异步调用前端页面的JavaScript相关函数,并通过Promise方式返回脚本执行的结果。runJavaScript需要在loadUrl完成后,比如onPageEnd中调用。

使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。注册应用侧代码有两种方式,一种在Web组件初始化调用,使用javaScriptProxy()接口。另外一种在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口。

4.4. 三层架构是什么?

官方文档 三层架构为了"一次开发,多端部署",项目结构采用三层架构 三层工程结构如下:

  • commons(公共能力层):用于存放公共基础能力集合(如工具库、公共配置等)。commons层可编译成一个或多个HAR包或HSP包,只可以被products和features依赖,不可以反向依赖。
  • features(基础特性层):开发页面、组件(HAR包或HSP包)。
  • products(产品定制层):定义phone\pad两个ability,引用 features 的包和 commons 的包完成应用功能
4.5. commonEventManager公共事件订阅踩坑

错误用法:subscribeEventHandler方法里,使用到this是为undefined

复制代码
this.subscriber = await commonEventManager.createSubscriber(this.subscriberInfo)
      commonEventManager.subscribe(this.subscriber, this.subscribeEventHandler)

正确用法:加上.bind(this)

复制代码
this.subscriber = await commonEventManager.createSubscriber(this.subscriberInfo)
      commonEventManager.subscribe(this.subscriber, this.subscribeEventHandler.bind(this))

原因:bind(this)来强行指定方法体的this为当前对象

5. 编程能力

5.1. 算法

任意说个算法

5.1.1. 开发模式MVC、MVVM等的理解
5.1.1.1. 如何提高代码质量
  • 变量命名清晰,尽量不缩写不简写
  • 方法行数、类行数控制,一个方法干一件事,一个类做一种事
  • 模块之间解耦合,互相之间通信通过回调、代理给到另外的模块处理
  • 单元测试、冒烟自测

6. 业务理解以及解决问题的能力

  • 项目有哪些印象深刻难题,怎么解决的
  • 有哪些亮点功能,大概讲一下

7. 面试结果

建议层级

面试外包对应的层级

w3对应s4,w4对应s5,老师给一个推荐层级

候选人优势

候选人不足

其他

面试结果

相关推荐
聪明的笨猪猪6 小时前
Java JVM “调优” 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
兩尛8 小时前
Spring面试
java·spring·面试
白云千载尽8 小时前
leetcode 912.排序数组
算法·leetcode·职场和发展
代码充电宝8 小时前
LeetCode 算法题【简单】290. 单词规律
java·算法·leetcode·职场和发展·哈希表
恋红尘10 小时前
Redis面试八股
数据库·redis·面试
hanxiaozhang201812 小时前
Netty面试重点-2
面试·netty
小龙报14 小时前
《彻底理解C语言指针全攻略(6)-- qsort、sizeof和strlen》
c语言·开发语言·职场和发展·创业创新·学习方法·业界资讯·visual studio
Swift社区16 小时前
LeetCode 402 - 移掉 K 位数字
算法·leetcode·职场和发展
墨染点香16 小时前
LeetCode 刷题【124. 二叉树中的最大路径和、125. 验证回文串】
算法·leetcode·职场和发展