鸿蒙面试题

鸿蒙面试题

1.MVVM模式


MVVM(Model-View-ViewModel)是一种软件架构设计模式,主要用于构建用户界面(UI)应用程序,特别是在那些支持数据绑定和声明式编程范式的框架中,如Vue.js和React等。MVVM是从经典的MVC(Model-View-Controller)模式演化而来,旨在进一步提升代码的可维护性、可测试性和可扩展性,尤其适用于复杂的客户端应用。

它由三个核心组成:
Model(模型层):
负责封装应用程序的数据结构、业务逻辑和数据访问层。
定义数据的获取、存储、处理和验证规则,以及业务逻辑和算法。
通常是POJO(Plain Old Java Object)或类,不包含任何与视图相关的代码。

View(视图层):
​ 用户界面的可视化部分,负责展示数据给用户,并接收用户的输入。
​ 视图是被动的,仅根据ViewModel提供的数据和指令来展示内容或响应用户操作。
​ 使用数据绑定技术,避免直接操控DOM或UI组件,使得视图逻辑更简洁。

ViewModel(视图模型):
​ 作为Model和View之间的桥梁,负责将Model中的数据转换成适合View使用的格式。
​ 含视图的状态和行为逻辑,如数据转换、命令绑定(用于处理用户操作)。
​ 通过双向数据绑定,ViewModel可以自动同步视图和模型的数据变化,只需关注数据和逻辑,无需手动管理UI更新。

2、页面生命周期、Ability生命周期

UIAbility的生命周期主要包括Create、Foreground、Background、Destroy四个状态。
先后顺序是Create状态,在应用加载过程中,UIAbility实例创建完成时触发
onWindowStageCreate创建窗口舞台
onForeground是UIAbility实例切换到前台时触发
Visible、Active获取焦点并可见
InVisible、InActive失去焦点 不可见
onBackground切换到后台时触发
销毁时会触发onWindowStageDestroy,再触发onDestory

页面的生命周期函数有5种,aboutToAppear、aboutToDisappear是任何页面都有的
onPageShow,onPageHide,onBackPress是只有被@Entry装饰器修饰的入口组件才可以调用
aboutToAppear方法是在组件被创建后执行build方法之前调用
onPageShow是在执行完build方法但还未将渲染的页面内容展示在窗口执行前执行
onBackPress是在点击返回按钮时触发,并且会删除当前页面,释放内存,触发当前页面的aboutToDisappear方法
onPageHide是在push到其他页面时触发,如果是router.back(),不仅会触发onPageHide还会触发当前页面的aboutToDisappear方法,因为back是弹栈,弹出的页面会被回收
在入口中如果调用了子组件,则渲染子组件时会触发子组件的aboutToAppear方法,如果因为状态的变更,导致子组件不再渲染,会触发子组件的aboutToDisappear方法

3、隐式want匹配规则

Want是对象间信息传递的载体,可以用于应用组件间的信息传递。
其使用场景之一是作为startAbility()的参数,包含了指定的启动目标以及启动时需携带的相关数据,如bundleName和abilityName字段分别指明目标Ability所在应用的包名以及对应包内的Ability名称。当UIAbilityA启动UIAbilityB并需要传入一些数据给UIAbilityB时,Want可以作为一个载体将数据传给UIAbilityB。

**显式Want:**在启动Ability时指定了abilityName和bundleName的Want称为显式Want
**隐式Want:**在启动UIAbility时未指定abilityName的Want称为隐式Want

系统将调用方传入的want参数(包含action、entities、uri和type属性)
与已安装待匹配的应用Ability的skills配置(包含actions、entities、uris和type属性)依次进行匹配。
当四个属性匹配均通过,则此应用才会被应用选择器展示给用户进行选择。

want参数的action匹配规则
调用方传入的want参数的action必须是待匹配Ability的skills配置中的actions的真子集(两边为空时匹配失败)

want参数的entities匹配规则
调用方传入的want参数的action必须是待匹配Ability的skills配置中的actions的子集(两边为空时匹配成功)

want参数的uri和type匹配规则
调用方传入的want参数中设置uri和type参数发起组件启动请求,系统会遍历当前系统已安装的组件列表,
并逐个匹配待匹配Ability的skills配置中的uris数组,
如果待匹配Ability的skills配置中的uris数组中只要有一个可以匹配调用方传入的want参数中设置的uri和type即为匹配成功。
(uris中有scheme、host、port、path、pathStartWith和pathRegex这些属性)

4、公共事件和通知

HarmonyOS通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力。

从系统角度可分为:系统公共事件和自定义公共事件。
**系统公共事件:**CES内部定义的公共事件,只有系统应用和系统服务才能发布,例如HAP安装,更新,卸载等公共事件
**自定义公共事件:**应用自定义一些公共事件用来实现跨进程的事件通信能力

按发送方式可分为:无序公共事件、有序公共事件和粘性公共事件
**无序公共事件:**CES转发公共事件时,不考虑订阅者是否接收到,且订阅者接收到的顺序与其订阅顺序无关
**有序公共事件:**CES转发公共事件时,根据订阅者设置的优先级等级,
优先将公共事件发送给优先级较高的订阅者,
等待其成功接收该公共事件之后再将事件发送给优先级较低的订阅者。

**粘性公共事件:**能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。
普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅。
发送粘性事件必须是系统应用或系统服务,且需要申请ohos.permission.COMMONEVENT_STICKY权限

公共事件模块:commonEventManager
主要方法:createSubscriber、subscribe、unsubscribe、publish

通知模块notification
HarmonyOS通过ANS(Advanced Notification Service,通知系统服务)对通知类型的消息进行管理,支持多种通知类型,如基础类型通知、进度条类型通知。
基础类型的通知:
普通文本型 NOTIFICATION_CONTEXT_BASIC_TEXT
长文本型 NOTIFICATION_CONTEXT_LONG_TEXT
多行文本型 NOTIFICATION_CONTEXT_MULTILINE
图片型 NOTIFICATION_CONTEXT_PICTURE
进度条类型的通知

1
2
3
4
5
6
isSupportTemplate('downloadTemplate')//查询是否支持进度条通知
// 构造进度条模板,name字段当前需要固定配置为downloadTemplate
template: {
name: 'downloadTemplate',
data: { title: 'File Title', fileName: 'music.mp4', progressValue: 45 }
}

5、状态管理

ArkTs会监听状态变量(被装饰器标记的变量),当某个事件改变了状态变量的值,会触发UI重新渲染。
**@State:**是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化,支持Object、class、string、number、boolean、enum类型,嵌套类型以及数组中的对象属性无法触发视图更新
**@Prop:**和父组件建立单向同步,只支持string、number、boolean、enum类型,父组件对象,子组件是对象属性
**@Link:**与其父组件中的数据建立双向绑定,禁止本地初始化,父子类型一致:string、number、Eumn、object、class以及它们的数组
**@Provide、@Consumer:**双向数据同步,跨组件、跨层级传递,配合使用可以实现不调用、不传参直接完成双向同步
**@Observe、@ObjectLink:**用于在涉及嵌套对象或数组的场景中进行双向数据同步,被@Observed装饰的类,可以被观察到属性的变化,子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例

6.配置文件

app.json5是全局配置信息:
bundleName:应用唯一标识
vendor:应用开发厂商描述
versionCode:版本号
versionName:版本描述
icon:应用图标
label:应用名

module.json5是Module的基本配置信息:
name:当前Module名称
type:当前Module的类型,entry/feature/har/shared
srcEntry:当前Module所对应的代码路径
deviceTypes:当前Module可以运行在哪类设备上
requestPermissions:申请的权限
abilities:当前Module中UIAbility的配置信息

main_pages.json是路由跳转的页面配置

7.多线程

HarmonyOS应用中每个进程都会有一个主线程,主线程有如下职责:

执行UI绘制;
管理主线程的ArkTS引擎实例,使多个UIAbility组件能够运行在其之上;
管理其他线程(例如Worker线程)的ArkTS引擎实例,例如启动和终止其他线程;
分发交互事件;
处理应用代码的回调,包括事件处理和生命周期管理;
接收Worker线程发送的消息;

除主线程外,还有一类与主线程并行的独立线程Worker,主要用于执行耗时操作,
但不可以直接操作UI。Worker线程在主线程中创建,与主线程相互独立。最多可以创建8个Worker

线程间通信目前主要有Emitter和Worker两种方式,其中Emitter主要适用于线程间的事件同步,
Worker主要用于新开一个线程执行耗时任务

8.Stage模型层次结构

一个应用包含一个或者多个Module,分为“Ability Module”功能模块和“Library Module”库模块,Ability Module编译后打包成HAP(Harmony Ability Package),Library Module打包成HAR或HSP,编译时的HAP和HSP共同组成一个Bundle,Bundle里包含一个Entry类型的HAP和一个或多个Feature类型的HAP

一个Module可以包含一个或多个UIAbility组件

每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码被加载到进程中的时候会创建AbilityStage应用组件的大舞台,它会持有一个context上下文,在这个舞台上创建UIAbility,然后在之上创建windowStage窗口舞台,然后在窗口舞台上创建window窗口,最后在窗口上显示我们的page

9.管理应用拥有的状态

AppStorage:应用全局的UI状态存储,在应用启动的时候会被创建的单例,属性通过唯一的键字符串值访问
@StorageProp(key)是和AppStorage中key对应的属性建立单向数据同步
@StorageLink(key)是和AppStorage中key对应的属性建立双向数据同步
LocalStorage:页面级UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例
LocalStorage也可以在UIAbility实例内,在页面间共享状态。
@LocalStorageProp:@LocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系
@LocalStorageLink:@LocalStorageLink装饰的变量和在@Component中创建与LocalStorage中给定属性建立双向同步关系。

Environment:设备环境查询,是ArkUI框架在应用程序启动时创建的单例对象,
Env-ironment的所有属性都是不可变的(即应用不可写入),所有的属性都是简单类型。

10.其它状态管理

@Watch装饰器:状态变量更改通知

@Watch用于监听状态变量的变化,变量初始化时不会调用,初始化完成后状态变量变化时,@Watch的回调方法将被调用

11.页面路由

Router有两种页面跳转模式,分别是:
router.pushUrl():目标页不会替换当前页,而是压入页面栈,因此可以用router.back()返回当前页
router.replaceUrl():目标页替换当前页面,当前页面会被销毁并释放资源,无法返回当前页

Router有两种页面实例模式,分别是:
Standard:标准实例模式,每个跳转都会新建一个目标页并压入栈顶–>默认模式
Single:单实例模式,如果目标页已经在栈中,则离栈顶最近的同URL页面会被移动到栈顶并重新加载
Ps:一般情况下,pushUrl + Single

12.UIAbility启动模式

Singleton:单实例模式,默认的模式,任务列表只会存在一个UIAbility
Multiton模式:多实例模式,每次点击桌面图标都会触发Ability重新创建,但任务列表只会有一个实例,原先的应用实例被删除,
Standard模式:多实例模式,每次点击图标都会创建一个新的实例,任务列表中存在一个或者多个相同的UIAbility
Specified模式:指定实例模式,每个UIAbility实例可以和一个Key绑定,启动UIAbility时,需要指定Key,存在Key相同实例直接拉起,不存在则创建新实例

2024年7月16日 上海屹通面试题

自我介绍:做了什么项目,用API几
1、页面和组件的生命周期(简单)

2、一段文本,分3个部分,分别设置样式,怎么做?(简单)
答案:一个Text里面放3个Span组件

3、自定义弹窗CustomDialog怎么用?
答案:使用@CustomDialog装饰器用于装饰自定义弹框,controller绑定弹窗控制器,在onClick事件中使用controller.open()和controller.close()

4、页面跳转方式,用什么方法(简单)
答案:router.pushUrl():目标页面不会替换当前页,而是压入页面栈,这样可以保留当前页的状态,router.replaceUrl():目标页面会替换当前页,并销毁当前页

5、页面栈有A、B、C、D四个页面,现在在D页面,怎么回到B页面
答案:第一可以用router.back()传入D页面的url进行跳转,第二可以用router.pushNamedRoute()命名路由跳转

6、侧滑手势的用法

7、AppStorage有没有使用过,说下实际使用场景

8、说下鸿蒙里面的状态管理
答案:最新API有V1和V2两张版本,主要说V1,最基本的@State、@Prop单向同步、@Link双向同步、@Consumer @Provide跨组件跨层级接收、@ObjectLink @Observe用于监听嵌套类型对象的变化