HarmonyOS面试题(持续更新中)
1、用过线程通信吗,线程是怎么进行通信的?
emitter 和 eventHub
相同:
都是基于事件总线的
区别是:
① eventHub当前线程内通信
② emitter是同一进程不同线程或者同一进程和同一线程也可以通信
2、页面和组件的生命周期
页面生命周期:
被@Entry装饰的组件生命周期,提供以下生命周期接口:
onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景
onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
onBackPress:当用户点击返回按钮时触发。
组件生命周期:
一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:
aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build0函数之前执行
onDidBuild:组件build(函数执行完成之后回调该接口,不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的U表现。
aboutToDisappear:aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。
3、UiAbility的生命周期呢?
onCreate
onWindowStateCreate
onForground
onBackground
onDestroy
onNewWant - 拉起ability 如果ability已经存在的情况下,onNewWant会执行
4、弹窗UI是怎么在页面UI中使用的
① CustomtDialogController
② 创建子窗口的形式创建弹层
③ 弹层
bindSheet 半层
bindContentCover 全层
5、常用的修饰符有哪些
State Prop Link Provide Consume Observed ObjectLink Builder BuilderParams Styles
Extends Require Entry Component CustomDialog Watch StorageProp StorageLink
LocalStorageProp LocalStorageLink Track Prewview
6、buffer是什么与16进制和数组有什么关系吗
缓冲区(Buffer)是一种用于临时存储数据的内存区域,它可以是一个连续的内存块,用于临时保存数据。在编程中,缓冲区通常用于存储二进制数据,比如字节序列。 与 16 进制和数组的关系如下:
-
16 进制表示:在计算机中,数据以二进制形式存储。当我们需要查看或者处理二进制数据时,通常使用 16 进制表示。例如,一个字节的二进制数据可以用两个十六进制数字表示。
-
数组:缓冲区可以看作是一个数组,其中的元素是字节(或者其他数据类型,取决于缓冲区的类型)。通过数组的索引,我们可以访问和修改缓冲区中的数据。
7、Builder和BuilderParams的区别
Builder是当前组件的UI复用结构 BuilderParams是接收父组件传入的UI复用结构, 传过来的类型是UI复用结构类型
Builder传值 想要响应式必须是对象,如果基础数据类型,不具备响应式
8、对于一些公共的样式你是怎么做的?有没有什么优化的方式
-
封装组件
-
提取Builder
-
提取Styles和Extends
8、鸿蒙和安卓和IOS的区别
从宏观上说鸿蒙借鉴了安卓的componse框架和ios的swiftUI, flutter的链式调用,还借鉴了前端的ts。API有点像安卓,但是从系统封闭性更像ios
9、鸿蒙的刷新机制是怎么样的,多层嵌套时,是从build开始刷新吗
刷新机制只检测第一层数据变化,不论什么修饰符,从最外层开始,但是会进行比较,如果该属性数据没有变化,该层级不刷新。只要key发生了变化,就会更新- 如果不给key, 那么就会实现index_JSON.stringify(item)的方式 是从build开始刷新,但是并不是开始更新- 只有对应数据变化了 才会进行组件的销毁去重新创建
10、发布的应用用什么监控的日志呢
自带的log,可以监听,也可以写入文件,但是写入文件一般都有限, 我们一般都是监听崩溃日志,将日志上报我们的服务器,监听崩溃日志就是个API
11、webSocket用过吗?说说你在项目中怎么用的
主要用在发消息和接消息,用于客服模块的消息
ws = webSocket.createWebSocket()
ws.connect("url", () => { })
ws.on("open", () => { })
ws.on("message", () => { })
ws.on("close", () => { })
ws.send(JSON.stringify(content))
12、多线程woker与emite的区别是什么?是否能自动更新UI?worker最大的数量是多少?
Worker和TaskPool 不能更新UI 最大数量8个, 用完worker要销毁
13、不使用CustomDialog和条件渲染怎么实现一个像prompt.showToast的弹窗效果
使用创建subwindow的方式来实现。传入一个参数,设置窗口的宽度和高度,创建弹窗,通过loadContent加载一个UI页面,页面中传入参数
14、@Provide和@Consume的使用中,消费者修改了值,提供者那边会变化吗?
当然会,因为都是双向的
15、输入框获取焦点,弹出键盘会将页面推至屏幕外,想正常显示,应该怎么处理?
设置键盘的避让模式
windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE)
16、页面转场是怎么实现的
动画 给图片一个id 设置一个属性,转场页面设置同一个id,既可以转场
17、客户端怎么实现长登陆的;再说说token的失效后是如何处理的?
-
token是登录之后得到的,如果失效应该去换取token,还应有一个refreshToken,
-
refreshToken换取一个新的token
-
如果换取成功-替换原有token-重启发请求
-
如果换取失败-删除token-删除refreshToken-跳转到登页有什么区别
18、除了har包和HSP包 还能打成什么包?
app- 综合包
har-静态包-会出现多次拷贝
hsp-共享包-只会有一次
hap- 带ability,只有它带
19、@Link和@Prop的区别
@Prop的数据是单向传递的,父组件改变能通知子组件,但是子组件改变不能通知父组件。
@Link的数据是双向传递的,父组件改变能通知子组件,子组件的改变也可以通知父组件。
20、 http是在主线程内还是另起一个线程?
http是在主线程内还是另起一个线程,每个请求通常都会由一个单独的线程来处理
21、Promise 异步、和TaskPool、Worker有什么区别吗
① Promise:异步仍然是在当前线程中运行任务,结果以异步方式返回
② TaskPool::对于一些耗时操作,使用Promise占用了主线程资源,可能会导致ANR,所以出现了taskPool来保证可以起子线程处理耗时操作。taskPool存活最长时间为3分钟,运行超过3分钟,那么会被系统杀掉。
③ Worker:存在一个特别耗时的操作,或者可能存在业务需要一直死循环运行。通过worker可以启动一个线程,该线程不存在时长限制,可以一直存在,所以我们可以在里边做一些耗时操作。worker线程最多可以在APP里同时存在8个一起运行,超出数量的不会运行。但是创建可以创建多个,所以当worker不需要的时候要及时停止运行。worker对内存有影响,每个空worker起来后就会占用2MB左右内存
22、多线程改变了主线程的值 那么主线程内的值会不会一起改变?
不会 。
主线程和子线程是独立运行的,它们拥有各自的栈空间。主线程和子线程在栈帧中保存的是各自的局部变量,这样就确保了它们的互不干扰。
23、TaskPool线程的数据怎么和主线程同步?
TaskPool的任务支持通过sendData接口触发主线程的onReceiveData回调,暂不支持主线程向子线程通信。
24、@Entry与@Component有什么区别?
@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。
@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。
25、want的type和action参数是做什么的
Want的type和action参数主要用于指定操作类型和动作。
Type:参数用于指定数据类型,它告诉系统或应用程序如何处理或显示数据。
Action:参数代表了一系列预定义的操作,这些操作描述了Want对象的用途或目的。
26、性能优化有哪些?
一、使用并行化、预加载和缓存等方法,提升系统资源利用率,减少主线程负载,加快应用的启动速度和响应速。
① 使用多线程执行耗时操作
② 使用异步执行耗时操作
③ 使用预加载提升页面启动和响应速度
④ 使用条件渲染实现预加载
⑤ 使用缓存提升启动速度和滑动帧率
二、尽量减少布局的嵌套层数
① 移除冗余节点,删除无用的Stack/Column/Row嵌套
② 使用Column/Row替代Flex构建线性布局
③ 使用Flex、List、Grid、RelativeContainer、绝对布局和自定义布局等构建复杂布局
三、合理管理状态变量
① 合理管理状态变量,减少不必要的参数层次传递
② 避免滥用@Provide+@Consume
③ 控制对象级状态变量成员数量
④ 避免不必要的创建和读取状态变量
四、合理使用系统接口,避免冗余操作
① 避免在系统高频调用进行冗余和耗时操作
② 避免在系统高频调用打印日志
③ 在Release版本中删除Debug日志
五、使用性能工具分析和定位问题
27、@Entry 装饰的页面,A 页面跳到 B 页面后再跳回 A 页面,如何获取 B 页面的返回值
router.back({
url: 'pages/Home',
params: {
info: '来自Home页'
}
})// 这些参数可以在目标页面中
// 通过调用 router.getParams() 方法进行获取
onPageShow() {
const params = router.getParams() as Record<string, string>
console.log(params)
}
28、 如何实现给父组件传递子组件
使用 @BuilderParam
29、HarmonyOS应用打包后的文件扩展名是?
打包后的文件扩展名为.hap(HarmonyOS Ability Package),这是HarmonyOS应用的标准包格式
30、如何进行数据持久化?
用户首选项(Preferences):这是一种轻量级的配置数据持久化方式,适用于保存应用配置信息、用户偏好设置等。
键值型数据库(KV-Store):适用于存储结构简单的数据,如商品名称和价格、员工工号和出勤状态等。
关系型数据库(RelationalStore):基于SQLite,适用于存储包含复杂关系的数据,如学生信息、雇员信息等
31、如何进行全局状态管理?
@Provide+@Consume装饰器
适用场景:适用于整个组件树而言“全局”的状态共享,且该状态改动不频繁的场景。
AppStorage
适用场景:适用于整个应用而言“全局”的变量或应用的主线程内多个 UIAbility
实例间的状态共享。
LocalStorage
适用场景:适用于单个Ability而言“全局”的变量,主要用于不同页面间的状态共享。
32、LocalStorage在应用重启后数据会消失吗?
会,因为LocalStorage 是一种用于页面或组件级别的数据存储方式,它允许开发者在页面或组件的生命周期内存储和检索数据。LocalStorage 的数据存储在内存中,因此它的读写速度相对较快。但是,当应用重启后,LocalStorage 中的数据会丢失。
33、兄弟组件如何通信?
① 通过公共父组件传递
如果两个组件是同一个父组件的子组件,可以通过父组件来传递数据或事件。父组件可以作为中介,将一个子组件的数据或事件传递给另一个子组件。
② 使用全局状态管理
使用全局状态管理(如 AppStorage、LocalStorage)来存储共享数据。兄弟组件可以独立地读取和更新这个全局状态,从而实现通信。
34、 跨设备通信的方式有哪些?
- 分布式软总线:一种高性能的通信机制,允许设备之间建立直接连接,进行数据传输。
- 蓝牙:使用标准的蓝牙技术进行设备间的通信。
- WLAN:通过WLAN网络实现设备间的通信。
- 远程服务调用:通过分布式任务调度实现跨设备的服务调用。
35、LazyForEach是什么
LazyForEach 是一个用于高效渲染列表的组件或功能,它允许开发者在用户滚动列表时才加载和渲染列表项,而不是一次性渲染整个列表。这种按需渲染的方式可以显著提高应用的性能,特别是在处理大量数据时。
36、显示 want 和 隐式 want 的区别?
显式Want:在启动目标应用组件时,调用方传入的want参数中指定了abilityName和bundleName,称为显式Want。
隐式Want:在启动目标应用组件时,调用方传入的want参数中未指定abilityName,称为隐式Want。
37、 三层架构是什么?
三层架构为了“一次开发,多端部署”,项目结构采用三层架构
三层工程结构如下:
commons(公共能力层):用于存放公共基础能力集合(如工具库、公共配置等)。commons层可编译成一个或多个HAR包或HSP包,只可以被products和features依赖,不可以反向依赖。
features(基础特性层):开发页面、组件(HAR包或HSP包)。
products(产品定制层):定义phone\pad两个ability,引用 features 的包和 commons 的包完成应用功能
38、本地缓存,数据持久化
Preferences:用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。
AppStorage + PersistentStorage(应用全局的 UI 状态存储)
KVStore(键值型数据库)
RdbStore(关系型数据库)
fs(写文件)