【HarmonyOS Next】鸿蒙应用常规面试题和答辩思路参考
【HarmonyOS Next】鸿蒙应用常规面试题和答辩思路参考
一、充分了解岗位JD要求
根据招聘发布的岗位JD,进行自我匹配分析。了解基本要求和加分项,以及项目节奏和英文要求等。
- 技术不匹配的点,是否会影响应聘岗位
- 加分项自己是否掌握,是否有亮点,提前和招聘同步,在简历中加粗标明
- 对于学历和工作经验要求,是否符合。若自己技术能力强,在行业内有一定影响力或者优秀的开源项目,询问招聘人是否有绿色通道【很关键】
- 准备自己与岗位相关的技能证书和荣誉证明
- 根据项目节奏分析自己是否可适应,并且了解公司所在地与自己通勤成本
二、面试前期准备工作
1.了解是否会有背景调查环节,检查自己的个人材料,查漏补缺
2.询问招聘对接人,面试范围,获取有用的信息,充分准备复习
3.完善简历中描述的项目经验【这很关键】,要清楚面试的目的,是公司需要验证候选人的技能能力和项目真实程度。
4.将自己负责的项目中,较为复杂的解决方案。问题的发现,定位和解决完整过程进行梳理。【但是要小心被对方套方案,如果面试人的问题很简单,这里可以斟酌模糊回答。】
5.针对面试官说,你有什么想问的,要表达自己对于岗位的疑问和对于工作内容的求知欲。
三、面试题参考
标准的面试环节,会根据你应聘的岗位级别,有针对的询问候选人。例如初中高三种级别,询问的内容是不尽相同的。
1. 是否了解HarmonyOS和OpenHarmony的区别?
HarmonyOS 是华为基于 OpenHarmony 等开发的商用版本,OpenHarmony 是开源项目,二者在性质来源、技术实现等方面存在差异。
回答出差异点与来源即可。
2.介绍一下你自己负责鸿蒙开发的较为复杂的功能有哪些?
建议根据自己的实际项目经验来准备。因为如果不是自己的开发的功能,面试官逐步问到细节,会导致出问题。当然能力强无所谓。
复杂度亮眼的功能,突出自己的工作能力,学习能力和解决问题的能力即可。
3. 举例V1状态装饰器有什么?是做什么的?
在鸿蒙开发中,状态装饰器是 ArkTS 语言里用于管理组件状态的关键工具,在早期版本(V1)中有以下常见的状态装饰器及其作用,以下是一个完整的鸿蒙开发示例,展示了如何使用 @State、@Prop、@Link、@Provide 和 @Consume 这些 V1 状态装饰器:
// 祖先组件,使用 @Provide 提供数据
struct AncestorComponent {
sharedMessage: string = '这是共享消息'
parentCount: number = 0
build() {
Column({ space: 50 }) {
// 父组件,传递数据给子组件
ParentComponent({ parentValue: $parentCount })
// 后代组件,消费共享数据
DescendantComponent()
}
}
}
// 父组件
struct ParentComponent {
parentValue: number
localCount: number = 0
build() {
Column({ space: 20 }) {
Text(`父组件本地计数: ${this.localCount}`)
Button('增加父组件本地计数')
.onClick(() => {
this.localCount++
})
Text(`从祖先组件传递过来的计数: ${this.parentValue}`)
Button('增加祖先组件传递过来的计数')
.onClick(() => {
this.parentValue++
})
// 子组件,接收父组件传递的数据
ChildComponent({
propValue: this.localCount,
linkValue: $localCount
})
}
}
}
// 子组件
struct ChildComponent {
propValue: number
linkValue: number
build() {
Column({ space: 20 }) {
Text(`通过 接收的父组件数据: ${this.propValue}`)
Text(`通过 绑定的父组件数据: ${this.linkValue}`)
Button('增加通过 @Link 绑定的数据')
.onClick(() => {
this.linkValue++
})
}
}
}
// 后代组件,使用 @Consume 消费共享数据
struct DescendantComponent {
sharedMessage: string
build() {
Column({ space: 20 }) {
Text(`通过 消费的共享消息: ${this.sharedMessage}`)
}
}
}
struct MainPage {
build() {
Column({ space: 50 }) {
// 渲染祖先组件
AncestorComponent()
}
}
}
4. V2状态装饰器主要解决了什么问题?都有什么?举几个例子即可
在鸿蒙开发中,ArkTS 从 V1 到 V2 状态装饰器的演进解决了一些开发中的痛点,提供了更简洁、更强大的状态管理能力。
参考:
【HarmonyOS Next】鸿蒙状态管理V2装饰器详解
【HarmonyOS Next】鸿蒙状态管理装饰器V1和V2混用方案
import { Component, build, Reactive, Watch, LinkState, View } from '@ohos/hypium';
// 定义一个响应式对象
class MyData {
name: string = 'John';
age: number = 25;
}
// 定义一个带有 @Watch 装饰器的响应式数据类
class MyReactiveData {
value: number = 0;
('value')
onValueChange(newValue: number, oldValue: number) {
console.log(`Value changed from ${oldValue} to ${newValue}`);
}
}
// 子组件,使用 @LinkState 进行双向数据绑定
struct Child {
parentValue: number;
build() {
Column({ space: 20 }) {
Text(`Value from parent: ${this.parentValue}`)
Button('Increment Value')
.onClick(() => {
this.parentValue++;
})
}
}
}
// 主组件,整合所有功能
struct MainComponent {
private myData = new MyData();
private reactiveData = new MyReactiveData();
myValue: number = 0;
build() {
Column({ space: 50 }) {
// @Reactive 示例
Column({ space: 20 }) {
Text(`Name: ${this.myData.name}, Age: ${this.myData.age}`)
Button('Update Data')
.onClick(() => {
this.myData.name = 'Jane';
this.myData.age = 30;
})
}
// @Watch 示例
Column({ space: 20 }) {
Text(`Value: ${this.reactiveData.value}`)
Button('Increment Value')
.onClick(() => {
this.reactiveData.value++;
})
}
// @LinkState 示例
Column({ space: 20 }) {
Text(`Parent value: ${this.myValue}`)
Child({ parentValue: this.myValue })
}
}
}
}
5. MVVM是什么?
MVVM(Model - View - ViewModel)是一种前端开发的软件设计模式,它是在 MVC(Model - View - Controller)和 MVP(Model - View - Presenter)模式的基础上发展而来,主要用于分离视图(UI)和业务逻辑,提高代码的可维护性、可测试性和可扩展性。
MVVM模式,应用的UI以及基础表示和业务逻辑被分成三个独立的类:视图,用于封装UI和UI逻辑;视图模型,用于封装表示逻辑和状态;以及模型,用于封装应用的业务逻辑和数据。
6. 自定义组件如何实现?
自定义组件可以将特定的 UI 元素和逻辑封装起来,提高代码的复用性和可维护性。
import { Component, build, Prop, Event } from '@ohos/hypium';
struct MyCustomComponent {
// 接收父组件传递的属性
title: string = '默认标题';
// 定义自定义事件
onCustomClick: () => void;
build() {
Column({ space: 20 }) {
Text(this.title)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Button('点击触发自定义事件')
.onClick(() => {
// 触发自定义事件
this.onCustomClick();
})
}
.width('100%')
.padding({ top: 20, bottom: 20, left: 10, right: 10 })
.backgroundColor('#F0F0F0')
}
}
export default MyCustomComponent;
7. 纯逻辑类中如何显示弹框?
两种思路,1.由于纯逻辑类没有直接操作 UI 的能力,需要通过回调机制与 UI 组件进行交互,让 UI 组件来负责弹框的显示 2.使用解耦UI的方案进行实现,例如官方提供的OpenCustomDialog或者subWindow等。
举例第一种方案,定义回调接口:在纯逻辑类中定义一个回调接口,用于通知 UI 组件显示弹框。
在纯逻辑类中触发回调:在需要显示弹框的逻辑处调用回调方法。
在 UI 组件中实现回调:在 UI 组件中实现回调接口的方法,在该方法中编写显示弹框的逻辑。
// 定义回调接口
interface ShowDialogCallback {
(message: string): void;
}
class LogicClass {
private showDialogCallback: ShowDialogCallback | null = null;
// 设置回调函数
setShowDialogCallback(callback: ShowDialogCallback) {
this.showDialogCallback = callback;
}
// 模拟业务逻辑,触发显示弹框
doBusinessLogic() {
// 模拟一些业务处理
const message = "这是弹框要显示的消息";
if (this.showDialogCallback) {
this.showDialogCallback(message);
}
}
}
export default LogicClass;
import { Component, build, AlertDialog } from '@ohos/hypium';
import LogicClass from './LogicClass.ets';
struct Index {
private logic: LogicClass = new LogicClass();
private showDialog: boolean = false;
private dialogMessage: string = '';
build() {
Column({ space: 50 }) {
Button('触发业务逻辑')
.onClick(() => {
this.logic.doBusinessLogic();
})
}
.width('100%')
.padding({ top: 50, bottom: 50, left: 20, right: 20 })
// 显示弹框
if (this.showDialog) {
AlertDialog({
title: '提示',
message: this.dialogMessage,
onOk: () => {
this.showDialog = false;
}
})
}
// 设置回调函数
this.logic.setShowDialogCallback((message) => {
this.dialogMessage = message;
this.showDialog = true;
});
}
}
8. HAR和HSP分别是什么?区别是什么?
纯血鸿蒙中,HAR 是静态资源共享包,用于存放图片、配置文件等不频繁变更的内容;HSP 是用于底层及应用层动态更新文件的包。二者区别在于存储内容和更新频率不同 。
9. HSP如何可以给其应用使用?
参考:【HarmonyOS Next】 鸿蒙应用useNormalizedOHMUrl详解
10. 应用切到后台后,如何保证任务继续进行?
在鸿蒙应用开发中,当应用切到后台后,系统会对应用进行一定的管控,以优化资源利用和用户体验。为保证任务在后台继续进行,可采用以下方式:
申请后台任务权限,需要配置权限ohos.permission.KEEP_BACKGROUND_RUNNING:
{
"module": {
"reqPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
"reason": "应用需要在后台持续执行任务",
"usedScene": {
"ability": [
"com.example.yourapp.MainAbility"
],
"when": "always"
}
}
]
}
}
或者使用服务(Service)组件。
11. UIAbility和Page以及组件的生命周期函数
UIAbility 有 onCreate、onWindowStageCreate 等生命周期函数用于自身创建、窗口阶段创建等阶段。
Page 有 onPageShow、onPageHide 等函数处理页面显示与隐藏等情况,aboutToAppear等。
组件则有自身从创建到销毁过程中的如 init、build、delete 等生命周期函数来管理其状态和渲染等操作。
11. router和Navigaiton的区别是什么?
在鸿蒙开发里,Router 和 Navigation 虽都用于页面导航,但存在明显差异。Router 功能基础,侧重于简单的页面切换,支持通过 URL 跳转,页面间数据传递需手动处理,适用于页面结构和导航逻辑简单的场景,因功能轻量,在简单场景下性能开销小、导航速度快,使用时主要调用 Router.pushUrl 方法;而 Navigation 功能更丰富,支持栈管理和便捷的返回数据处理,适合复杂导航及需处理返回数据的场景,不过因管理页面栈等操作性能开销稍大。
12. 数据临时和持久存储技术方案是什么?
数据临时存储可使用内存变量,在程序运行期间保存数据,应用关闭或进程被杀时数据丢失;还能利用函数内部的局部变量实现临时存储。而数据持久存储方面,可采用 LocalStorage,它能在本地存储数据,即使应用关闭或进程被杀,数据依然保留,存储容量有限,约 5 - 10 兆;APP Storage 也是常用方案,它存储无限制,数据存于沙箱,仅卸载应用时数据才被清除;此外,还能借助数据库,如关系型数据库或轻量级的文件数据库,来高效管理和持久存储结构化数据,满足复杂数据存储和查询需求。
13. 悬浮球如何实现?
在纯血鸿蒙中实现悬浮球,可先在配置文件里声明所需权限,如窗口显示相关权限。接着创建自定义组件作为悬浮球的 UI,设置其样式,如大小、颜色、形状等。通过系统提供的窗口管理 API 创建一个悬浮窗口,将自定义的悬浮球组件添加到该窗口中。为实现悬浮球的移动功能,要监听触摸事件,根据触摸点的坐标变化更新悬浮球的位置。同时可添加点击、长按等交互事件处理逻辑,例如点击时弹出菜单、长按可进行拖动等。最后,对悬浮球的显示和隐藏进行控制,比如在特定条件下隐藏或显示悬浮球,确保在不同场景下都能合理使用。
14. 鸿蒙应用的进程和线程
参考:【HarmonyOS Next】鸿蒙应用进程和线程详解
进程是系统进行资源分配和调度的基本单位,每个鸿蒙应用至少有一个主进程,应用启动时系统会为其分配进程资源。应用可通过配置文件声明多进程,以实现不同功能模块的隔离,提高应用的稳定性和性能,比如将数据处理、网络请求等操作放在独立进程中。线程则是进程内的执行单元,一个进程可包含多个线程。主进程中有主线程负责处理 UI 渲染和用户交互,为避免阻塞主线程导致界面卡顿,耗时操作如网络请求、文件读写等需放在子线程中执行,可使用鸿蒙提供的线程池、异步任务框架等实现多线程编程,合理利用线程能充分发挥设备多核性能,提升应用响应速度和整体性能。
15. 鸿蒙应用如何实现子线程?
参考:【HarmonyOS Next】鸿蒙TaskPool和Worker详解 (一)
16. worker和taskPool的区别
任务池(taskpool):任务池为应用程序提供一个多线程的运行环境。它主要用于处理耗时的计算任务或其他密集型任务,可以有效地避免这些任务阻塞主线程。这样不仅能最大化系统的利用率,还能降低整体资源的消耗并提高系统的整体性能。
Promise是一种用于处理异步操作的对象。它代表了一个最终可能完成(或失败)的操作及其结果值的对象。与任务池不同,Promise主要用于处理异步操作,而不是多线程计算任务。
17. webview如何和原生双向通信?
runJavaScript:异步执行JavaScript脚本,并通过回调方式返回脚本执行的结果。
onConfirm:网页调用confirm()告警时触发此回调。
或在h5注册map与回调,通过调用注册的回调方法向ArkTS侧传递数据
18.forEach与LazyforEach 还有repeat的使用与区别?
参考:
【HarmonyOS Next】鸿蒙循环渲染ForEach,LazyForEach,Repeat使用心得体会
19.折叠屏如何适配,方案有哪些?
布局适配方面,可采用响应式布局,利用弹性容器、百分比和媒体查询等技术,使界面元素能依据屏幕尺寸与比例自动调整大小和位置;采用多窗口布局,针对不同折叠状态提供不同的布局方案,如单屏、分屏等模式。资源适配时,需准备多套不同分辨率和尺寸的图片、图标等资源,以便系统根据屏幕情况加载合适的资源。交互适配要考虑不同折叠形态下用户的操作习惯变化,例如在大屏模式下支持多任务操作、手势操作等;同时,为避免因屏幕折叠引发数据丢失或异常,需做好状态保存与恢复,在屏幕折叠前后保存和恢复应用的关键数据、界面状态等。此外,还可进行性能优化,合理分配资源,避免在折叠屏设备上出现性能瓶颈。
Navigaiton分栏,全屏自适应➕布局宽高监听➕子窗口变化监听
栅栏布局➕设备媒体查询。
20.鸿蒙如何打包插件和应用?
打包应用时,首先要确保项目代码开发完成且无错误,在 DevEco Studio 里,通过配置 config.json 文件明确应用的基本信息、权限需求等;接着,选择合适的构建方式,可使用 Studio 自带的构建工具,按提示完成签名配置,包括选择签名类型、创建或导入密钥等;最后执行构建任务,系统会生成 .hap(HarmonyOS Ability Package)或 .app 格式的应用安装包。而打包插件,若为 HSP(HarmonyOS Service Package)插件,同样先完善代码开发,在 config.json 里对插件进行详细配置,明确插件类型、入口文件等信息;之后进行编译操作,完成签名后即可生成 .hsp 格式的插件包。无论打包应用还是插件,都要确保配置准确、签名合规,以保证能正常安装和使用。