鸿蒙常见面试题(欢迎投稿一起完善持续更新——已更新到62)

1、forEach与LazyforEach 长列表优化 LayForEach(虚拟列表)

ForEach 全量渲染,滚动给触底加载更多时,数据量越多,内存占用就越大。

(列表数据较少,数据一次性全量加载不是性能瓶颈时。ForEach相对LazyForEach,代码简单很多。)

LazyForEach 按可视区域渲染,懒加载,没看到的内容不加载不渲染,长列表渲染。(列表数据较长,一次性加载所有的列表数据创建、渲染页面产生性能瓶颈时。)

LazyForEach 需要准备一个 IDataSource 类。其实这个类就是把数组的增删查改用 IDataSource 这个类重新实现一遍,同时通知 LazyForEach 组件需要对应的更新。

2、两种路由方案 (Navigation ) router:不推荐

● 组件导航 (Navigation)(推荐)

● 页面路由 (@ohos.router)(不推荐)

二者都可以实现页面跳转,页面传参,页面替换、页面返回等常规操作。

更推荐用 Navigation 得方式实现路由管理,原因:

  1. Navigation没有路由数量限制,Router限制32个。

  2. Navigation 支持一多能力,支持自适应单栏跟双栏显示。

  3. Navigation 支持路由拦截和删除指定页面。我们做卡片业务时进入应用的场景,

如果反复点击同一个卡片进入同样的页面,可以通过路由拦截删除重复的页面,

确保打开的只有一个。比如:用户登录失效,删除所有需要用户身份校验的页面。

  1. 模态嵌套路由 - Navigation可以嵌套在模态对话框中,也就是说可以模态框中

定义路由,Router不支持;(得自己研究一下)

3、你认为harmonyOS 和openHasrmony的区别是什么?(开源鸿蒙与华为鸿蒙)

OPenHarmony 开源鸿蒙--系统底座(设备开发硬件方面--应用开发软件方面)

HarmonyOS 华为鸿蒙-就是在开源鸿蒙的基础上,添加华为各种服务:如华为登录,

华为地图、华为分享。华为推送等

4、鸿蒙和安卓 ios的区别是什么?

鸿蒙在4.0版本之前,支持apk安装。在这之后式不支持安卓的apk

鸿蒙同时也参考安卓和ios许多优秀的设计,比如声明式的UI布局,安卓的compose

原生组件也有好多借鉴了IOS组件,比如渲染 推送机制,权限管理。

还有一个区别就是权限限制, 我觉得鸿蒙做的很好,隐私的升级,

照片隐私,并不是访问整个相册,而是选那个只能看那个,在代码编译的时候

可以通过picker实现,无需申请相片权限。

5、鸿蒙一多开发(页面适配)?

A**:自适应布局**(七种自适应布局能力): 拉伸、均分、占比、缩放、延伸、隐藏、折行

(比如手机上是搜索和分类是两行的 但在平板上是一行的)

占比能力:layoutWeight

拉伸:flex布局 --flexGrow、flexShrink属性

(拉伸:伸缩 flexShrink缩 flexGrow伸 layoutWeight(同时伸缩))

延伸:scroll、grid、list waterFlow

(滑动能力--注意list默认垂直方向,在list加一个

.listDirection(Axis.Horizontal) //变成水平方向

.lanes(2) //两行交叉轴列数)

(方法二 scroll(this.scroller){Row() })

缩放能力:aspectRatio属性

(比如 width(100)aspectRatio(1)意思宽/高---网络图片需要设置宽高比)

均分:row组件 column flex组件的justifyContent属性

隐藏:displayPriority属性

折行:Flex组件的wrap属性设置为FlexWrap.Wrap

响应式布局(布局变动较大,无法自适应)

(比如在手机上tab首页 我的 分类 购物车在底部---但是在平板上tab就在左边 )

比如像是断点 媒体查询 栅格布局

断点--我们自己封装一个断点工具类,让原本不支持断点的组件也能根

据断点做适配。自带断点-xs(手表) sm (手机)md(折叠屏幕)lg(平板 三折屏)

媒体查询--深色模式,是否旋转。

栅格布局:栅格的样式由Margin、Gutter、Columns三个属性决定。

功能级一多: API适配 -CanIUse、try catch

工程级一多:三层工程架构-common fetaure product 可适当展开 hap hsp har 包

6、hap hsp har 包?

hap 应用的功能模块,可以独立安装和运行。必须包含一个entry类型的HAP,

可选包含一个或多个feature类型的hap、

har 静态共享包,编译态复用。

hsp 动态共享包,运行时复用。

HAP:是鸿蒙应用的核心部分,应用安装和运行的基本单元。支持在配置文件中声明abilities、extensionAbilities组件,支持在配置文件中声明pages页面。

HAR:静态共享包。编译态复用,不支持在配置文件中声明pages页面,支持Navigation组件导航。 不支持在配置文件中声明abilities、extensionAbilities组件;

主要使用场景:

作为二方库,发布到OHPM私仓,供公司内部其他应用依赖使用。

作为三方库,发布到OHPM中心仓,供其他应用依赖使用。 axios

HSP:动态共享包。运行时复用,不支持在配置文件中声明abilities、extensionAbilities组件,支持在配置文件中声明pages页面。

主要使用场景:

多模块共用的代码、资源可以使用HSP,提高代码的可重用性和可维护性。

元服务分包预加载。

7、LocalStorage&AppStorage&PeresistentStorage分别介绍一下?

LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility内,页面间共享状态。LocalStorage是一个局部的状态管理器。它修饰的变量保存在内存中,是非持久化状态,退出应用程序后会消失。

一个应用可能有若干个UIAbility,如果要在多个UIAbility共享数据,就可以使用AppStorage。AppStorage是一个全局的状态管理器,它修饰的变量保存在内存中,是非持久化状态,退出应用程序后会消失。应用退出再次启动后,依然能保存选定的结果,是应用开发中十分常见的现象,这就需要用到PersistentStorage。它修饰的变量保存在磁盘中,是持久化状态,退出应用程序依然存在。

PersistentStorage是应用程序中的可选单列对象。此对象的作用是持久化存储选定的AppStorage属性,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。

8、鸿蒙中,有那些弹窗组件?

1.ToastDialog(轻提示框)

功能和特点:用于在屏幕上短暂显示提示信息,不会打断用户的当前操作作流程。它会自动消失,通常用于显示一些简单的通知,如操作成功、加载完成等消息。

复制代码
ToastDialog toastDialog = new ToastDialog(getContext());
toastDialog.setText("操作成功");
toastDialog.show();

在上述代码中,getContext()是获取上下文环境的方法,用于正确显示对话框。setText方法用于设置提示框中显示的文本内容,show方法则是将提示框显示在屏幕上。

2、Dialog(对话框)

功能和特点:是一个可以包含标题、内容和按钮等多种元素的弹窗。它会中断用户当前的操作,直到用户对对话框进行操作(如点击按钮)后才会关闭。可以用于获取用户的确认、输入信息等多种场景。

复制代码
Dialog dialog = new Dialog(getContext());
// 设置对话框的布局
DirectionalLayout layout = new DirectionalLayout(getContext());
Text text = new Text(getContext());
text.setText("这是对话框的内容");
layout.addComponent(text);
dialog.setContentArea(layout);
Button button = new Button(getContext());
button.setText("确定");
button.setClickedListener(component -> dialog.close());
layout.addComponent(button);
dialog.show();

3.PopupWindow(弹出式窗口)

功能和特点:可以在指定位置(如某个视图旁边或屏幕的某个位置)弹出一个窗口,它的位置和显示方式比较灵活。可以用于显示菜单、工具提示或者一些自定义的小型交互界面。

复制代码
PopupWindow popupWindow = new PopupWindow(getContext());
// 设置PopupWindow的布局内容
DirectionalLayout layout = new DirectionalLayout(getContext());
Text text = new Text(getContext());
text.setText("这是PopupWindow的内容");
layout.addComponent(text);
popupWindow.setContent(layout);
// 设置PopupWindow的显示位置等属性
Component anchor = findComponentById(ResourceTable.Id_anchor_view);
popupWindow.showAsDropDown(anchor);

9、用过哪些装饰器,分别介绍一下?

组件相关装饰器

**@entry:**用于标记页面的入口组件,一个页面中最多只能由一个组件被@entry装饰。

**@component:**只能装饰用struct关键字声明的数据结构,被装饰的struct具备组件化的能力,需要实现build方法来描述UI,且一个struct只能被一个@component装饰。

**@Preview:**与@entry和@component结合实现预览功能,方便开发者在开发过程中快速查看组建的外观和效果。

数据传递与状态管理装饰器

**@state:**将类或者对象的属性标记为状态变量,当状态发生变化时,UI组件会相应地更新,常用于在组件内部管理状态。

**@prop:**用于单向同步父组件传递的数据到子组件,子组件可以使用该数据,但不能直接修改父组件中的原始数据。

**@Link:**实现父子组件之间的数据双向传递,当父组件中的数据变化时,子组件会相应更新反之,子组件中数据的变化也会反映带父组件中。

**@prvoide和@consume:**这两个装饰器形成生产者-消费者模式,用于跨组件传值,可实现与后代组件的数据双向同步,方便子啊不同层级的组件之间共享和更新数据。

**@storageLink和@storageProp:**作用于全局色UI状态存储,可以再不同页面之间共享和更新数据。@LocalStorageLink和@LocalStorageProp:用于页面级别的状态存储,再同一个页面内共享数据。

UI构建与复用装饰器

**@Builder:**将重复使用的UI元素抽象成一个方法。使用该装饰器修饰后,在Builder方法里可以调用,提高了代码的复用性。按引用传递参数时,传递的参数可为状态变量。且状态变量的改变会引起@builder方法内的UI刷新,ArkUI提供$$作为按引用传递参数的范式。

**@BuilderParam:**用来咋说指向@builder方法的变量,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能,类似slot占位符。

样式相关装饰器

@styles:可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用,用于快速定义并复用自定义样式。

@Extends:在@styles的基础上,用于扩展原生组件样式,与@Styles不同的是,@Extend装饰的方法支持参数,其他装饰器

10、ArkTS和TS有什么区别?

ArkTS是强类型,打包编译的时候会保留类型,提高程序运行效率

TS支持类型校验,但是并不严格,支持any、unknown这些不明确的类型,编译后其实js+d.ts,js文件不保留类型。

ArkTS禁用的类型

比如对象不能随意添加或者删除某些属性,对象类型要明确

需提前用interface或class 把对象的类型定义好

禁用了解构赋值

展开运算符 只支持数组,不支持对象展开

禁用call、apply、bind 这些方法改变this 指向

禁用any unknown 这些不明确的类型

通过@state @props 装饰器声明数据的时候,必须指定类型

总体而言,ArkTS 语法借鉴TS但更严格,以适应鸿蒙开发需求。

**11、**鸿蒙组件通信如何实现?有几种方式?(父传子 子传父)

(父传子、子传父,跨层级,跨页面)

父传子:

单向: 1. 没有装饰器直接传能接收,但是不能更新; 2.或者时通过@prop接收,父组件如果数据是@state装饰得数据,父组件数据更新,子组件能接收到更新

双向:1、通过@Link装饰的,要求父组件必须是 响应式的数据如:@State,子组件修改数据,父组件也能更新。2、@provide、@Consume也能实现,不过这组装饰器更多是用于跨层级。

全局:1.emitter通过定义事件,触发事件实现数据传递,属于线程通讯,跨组件,跨页面通讯都可以。 2.Appstroage。localstoreage也可以。

子传父:

传回调函数:子组件定义函数类型,父组件传递函数,子组件内部调用这个函数,通过回调函数把参数传递给父组件。

双向:@Link @Provide @conmuse

全局:emitter AppStroage

跨层级:

双向:@provide @consume

全局: emitter AppStroage

跨页面;

router路由: router.pushUrl({params:id})

Navigation路由:NavPageStack.pushPath({params.id})

@provide定义到根组件,子页面都能通过@consume访问

全局: emitter AppStroage

**12、**组件的生命周期有哪些大概说一下?

(通用组件 / 自定义组件 / 被@Entry修饰过的自定义组件 / NavDestination / Web )

通用组件:onAppear onDisAppear / onAttach12+ onDetach12+

自定义组件:aboutToAppear / aboutToDisAppear / onDidBuild12+

/aboutToReuse10+ / aboutToRecycle10+

被 @Entry 修饰过的自定义组件:onPageShow / onPageHide

/ onBackPress

NavDestination 组件:onShown / onHidden / onWillAppear

/ onWillShow /onWillHide /onWillDisappear / onBackPressed / ...

Web 组件:onPageBegin / onPageEnd / onProgressChange / ...

**组件生命周期(仅@Component):
aboutToAppear(),**aboutToDisappear()

页面生命周期(仅@Entry) :因为@Entry 也是@Component组件,所以页面组件同时拥有自定义组件的生命周期。

onPageShow(),

onBackPress(),

onPageHide(),

aboutToAppear(),

aboutToDisappear()

**13、**ability 的生命周期

onCreate(want, launchParam):在UI创建后执行,用于执行初始化操作,设置初始状态,注册监听器等

onDestroy():在UI销毁后执行,用于进行清理操作,释放资源等。

onWindowStageCreate(windowStage: window.WindowStage):在主窗口创建后执行,可以设置主页面并进行一些UI相关的操作。

onWindowStageDestroy():在主窗口销毁后执行,用于释放与UI相关的资源。

onForeground():在Ability进入前台后执行,可以执行一些与前台显示相关的操作。

onBackground():在Ability切换到后台后执行,可以执行一些与后台运行相关的操作。

**14、**navigation生命周期(路由跳转)

**aboutToAppear:**在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。

**onWillAppear:**NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。

**onWillDisappear:**NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。

**onAppear:**通用生命周期事件,NavDestination组件挂载到组件树时执行。

**onDisappear:**通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。

**onWillShow:**NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。

**onWillHide:**NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。

**onHidden:**NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。

**onShown:**NavDestination组件布局显示之后执行,此时页面已完成布局。

**aboutToDisappear:**自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。

15、web组件生命周期

onControllerAttached事件:Controller成功绑定Web组件时触发该回调,且禁止在该事件回调前调用Web组件相关的接口,否则会抛出js-error异常。

onLoadIntercept事件:当Web组件加载url之前触发该回调,用于判断是否阻止此次访问。默认允许加载。

onInterceptRequest事件:当Web组件加载url之前触发该回调,用于拦截url并返回响应数据。

onPageBegin事件:网页开始加载时触发该回调,

onProgressChange事件:可以从这个回调获取当前页面加载进度

onPageEnd事件:网页加载完成时触发该回调

16、Localstorage和appStorage的区别,和对应的装饰器?

Localstorage是页面数据布局,在页面中创建实例,组件中使用@localStoragelink和@Localstorageprop装饰器修饰对应的状态变量,绑定对应的组件使用比状态属性更灵活。

Appstorage是进程级数据存储,进程启动时自动创建了唯一实例,在各个页面组件中@storageprop和storageLink装饰器修饰对应状态变量。

Localstorage和appstorage数据存取都是在主线程进行得,且api只提供了同步接口,存取数据时要注意数据得大小。

17、实现多线程、有实际使用过嘛?什么情况下会使用

在ArkTS中实现多线程主要通过两种机制: worker和TaskPool

Worker:

用途:在后台线程中执行任务,避免阻塞主线程。

使用场景:处理耗时操作,如网络请求,文件读写等。

特点:有生命周期,需要手动去控制,最多课创建64个worker子线程等等。

语法:首先需要先新建一个worker.ets 的文件(会在builder-profile.json中自动配置文件路径,在需要处理业务的页面new一个worker,使用他的threadworker方法配置worker文件路径,通过这个实例的postmessage方法下发任务,在worker.ets的onmessage处理收到的任务,当任务完成以后,子线程可以使用postmessage反馈消息通知到主线程,同时使用close可以关闭子线程,任务结束。)

Taskpool

用途:管理多个后台任务,支持任务的并发执行;

使用场景:需要同时处理多个任务,如批量下载,批量上传等

特点:有时长限制,运行时长3分钟,taskpool可以设置任务优先级,worker不支持,任务量大或者调度分散的任务优先考虑使用taskpool(官方推荐)

语法:首先封装需要处理业务的函数(耗时较长,会堵塞主线程),装饰器使用@concurrent,函数返回值就是任务完成的结果,然后new taskpool,task (封装的函数,参数),返回值就是构建完成的任务,再调用taskpool,execute(任务)方法执行任务,它是promise,再主线程接收结果就ok了

多线程场景:图片视频解码、压缩、解压缩、Json解析、模型运算、数据库操作、网络下载。

18、用过哪些组件,分别介绍一下?

基础组件

  • Text:用于在界面上显示文本内容。可设置文本内容、字体大小、颜色、粗细、对齐方式等属性,还能通过添加样式来改变文本的外观和风格,例如实现阴影、下划线等效果。
  • Image:主要用于展示图片。能够设置图片源,支持网络图片、本地图片等多种来源,同时可设置图片的宽度、高度、边框圆角、缩放模式等属性,以适应不同的布局和展示需求。
  • TextInput:是接收用户文本输入的组件。可以设置占位符提示用户输入内容,指定文本类型,如密码、邮箱等,还能监听输入事件,在用户输入变化时执行相应的回调函数,用于实时验证或处理用户输入的数据。
  • Button:用于响应用户的点击操作。可设置按钮上显示的文字、按钮的类型,如普通按钮、胶囊按钮等,还能定义点击效果,如按下时的颜色变化、动画效果等,通过绑定点击事件来执行相应的业务逻辑。 -

容器组件

  • Column:是沿垂直方向布局的容器组件,子组件会按照顺序从上到下排列。可通过设置对齐方式、间距等属性来控制子组件的布局方式,常用于构建垂直排列的界面元素,如列表、表单等。
  • Row:沿水平方向布局的容器组件,子组件从左到右依次排列。同样可以设置对齐方式、间距等属性,适用于需要水平排列的组件,如导航栏、水平菜单等。
  • Stack:子组件按照顺序依次入栈,后一个子组件会覆盖前一个子组件。可用于实现重叠布局,例如在图片上添加文字说明、创建带有遮罩层的效果等,通过设置子组件的透明度和层级关系来控制显示效果。
  • Flex:以弹性方式布局子组件的容器组件,能根据可用空间自动调整子组件的大小和位置。可以设置主轴方向、交叉轴方向的对齐方式、子组件的弹性系数等属性,提供了非常灵活的布局方式,适用于各种复杂的界面布局需求。
  • List:用于展示一系列相同宽度的列表项。通常配合ListItem或ListItemGroup使用,可方便地展示分组列表项,支持数据绑定和列表项的动态更新,能实现各种类型的列表,如新闻列表、商品列表等。
  • Grid:由"行"和"列"分割的单元格所组成,通过指定"项目"所在的单元格来进行布局。可以设置行数、列数、单元格间距等属性,常用于展示图片墙、图标矩阵等需要网格布局的场景。

媒体组件

  • Video:用于在界面上播放视频内容。支持设置视频源、控制播放状态,如播放、暂停、停止等,还能调整视频的音量、亮度、对比度等参数,以及设置视频的填充模式和播放循环方式等。
  • Audio:主要用于播放音频内容。可以设置音频源、控制播放、暂停、切换音频等操作,同时支持调节音量、播放进度等功能,还能监听音频的播放状态变化事件。

其他组件

  • Span:作为Text组件的子组件,用于显示行内文本片段。可以为不同的文本片段设置不同的样式,如颜色、字体大小等,从而在一个Text组件中实现多种样式的文本显示。
  • Blank:在容器主轴方向上,具有自动填充容器空余部分的能力,常用于布局中需要占位或填充空白区域的场景,以实现组件的自适应布局。
  • Divider:用于分隔不同内容块或内容元素,可设置分隔线的颜色、粗细、样式等属性,使界面的结构更加清晰,内容分组更加明确。

19、 Row 组件如何将元素放到右下⻆?

可以通过设置Row的justifyContent为flex-end和alignItems为flex-end来实现。

20、子线程和主线程如何通讯?

⼦线程可以通过消息传递机制与主线程通讯,例如使⽤postMessage。

21、性能优化可以分为4方面

首先是布局

  1. 布局嵌套比较深的情况下应该使用相对布局,定位,Grid,GridRow等等扁平化布局,减少布局嵌套层数。
  2. 合理的使用状态变量,避免创建读取不必要的状态变量,避免滥用@provide和@consume
  3. 合理使用系统的高频回调接口,删除不必要的日志打印,减少系统开销。
  4. 合理地使用并行化、预加载和缓存等方法,提升系统资源利用率,减少主线程负载,加快应用的启动速度和响应速度。

比方说:

自定义组件创建完成之后,在build函数执行之前,将先执行aboutToppear()生命周期回调函数。此时若在该函数中执行耗时操作,将阻塞UI渲染,增加UI主线程负担,因此,

22、Builder和BuildParams的区别

在鸿蒙开发中,BuilderBuildParams有以下区别:

  • 功能用途
  • Builder :是一种装饰器,用于定义组件的声明式 UI 描述,将重复使用的 UI 元素抽象成一个方法,以实现轻量级的 UI 复用结构。比如,在多个地方需要显示一个特定样式的按钮,就可以用Builder来定义这个按钮的构建过程,然后在不同地方调用。
  • BuildParams:也是一种装饰器,用于修饰自定义组件内函数类型的属性,主要作用是允许父组件向子组件传递 UI 结构,类似于前端中 Vue 的插槽(slot)。
  • 定义位置与调用方式
  • Builder :可以定义在组件内或全局。在组件内定义的Builder方法可通过this访问当前组件的属性和方法,在组件的build方法和其他自定义构建函数中调用;全局的Builder方法可被整个应用获取,但不能使用thisbind方法。
  • BuildParams :通常在子组件中定义,在父组件中传入BuildParams对应的函数来使用。该函数可以没有Builder修饰,但必须调用一个Builder修饰的函数。
  • 参数传递与响应式特性
  • Builder :具有按值传递和按引用传递两种参数传递机制。按引用传递时,若传递的参数为状态变量,状态变量的变化会触发Builder方法内部 UI 的刷新;按值传递时则不会
  • BuildParams :本身不直接涉及参数传递的响应式问题,它主要是传递 UI 结构,由传入的Builder修饰的函数来处理参数和响应式。

23、简述鸿蒙打包流程

鸿蒙打包流程包括:

编译源代码⽣成中间⽂件。

通过构建⼯具(如DevEco Studio)将中间⽂件打包为HAP⽂件。

⽣成应⽤的manifest⽂件和资源⽂件。

进⾏签名和加密处理,确保应⽤的安全性。

最终⽣成可安装的HAP⽂件。

24、 数据持久化的⽅案?

在鸿蒙中,数据持久化的⽅案包括:

Preferences():⽤于存储简单的键值对数据,适合保存⽤户偏好设置。

数据库:使⽤SQLite等数据库存储结构化数据,适合复杂的查询和数据管理。

⽂件存储:将数据以⽂件形式存储在设备上,适合存储⼤⽂件或媒体⽂件。

分布式数据存储:⽤于在多设备间同步数据,⽀持云端存储。

25、给对象做类型可以⽤哪些⽅式? interface和type的区别?

给对象设置类型可以使⽤interface和type关键字。interface⽤于定义对象的结构,可以被多个对象

实现;type⽤于定义更复杂的类型,包括联合类型和交叉类型,不能被实现,但可以扩展。

26、 鸿蒙组件是如何通信的? @provide()和@consume()的使⽤?

在鸿蒙中,组件之间的通信可以通过@provide和@consume装饰器实现。@provide⽤于在⽗组件

中提供数据或状态,@consume⽤于在⼦组件中获取这些数据。通过这种⽅式,⽗⼦组件可以实现

数据的共享和状态的管理,避免了直接通过prop传递的复杂性。

27、 首选项通过什么方式存储?存储什么地方?

**数据持久化:**首选数据会被持久化存储,即使应用程序关闭或设备重启,数据也不会丢失。这是通过鸿蒙系统得存储机制来实现的,它会将首选项数据保存在特定的存储位置,确保数据的持久性。

**应用私有存储目录:**首选项通常存储在应用的私有存储目录中。每个应用在设备上都有自己 独立的私有存储区域,其他应用无法直接访问。这样可以保证首选项数据的安全性和独立性,不同应用之间的数据不会相互干扰。具体的存储路径可能因设备和鸿蒙系统版本而有所不同,但一般来说,它是在应用的专属存储目录下的一个特定文件或文件夹中。

28、 谈谈对生命周期的理解

在鸿蒙开发中,理解生命周期至关重要,它涵盖了应用、页面和组件等多个层面。以下是具体的理解:

应用生命周期:

  • 概念:指从应用启动到销毁的整个过程,包括应用的创建、初始化、前台运行、后台运行和销毁等阶段。
  • 作用:通过特定的回调函数来实现各个阶段,开发者可以在这些回调中执行相应的操作,如在创建阶段初始化应用所需的数据和资源,在销毁阶段释放所有占用的系统资源,并保存必要的数据。
  • 具体函数:
  1. onCreate():应用创建时调用,用于进行一些初始化操作,比如加载配置文件、初始化数据库连接等。
  2. onWindowStageCreate():WindowStage创建完成后调用,可以在此设置UI加载、设置WindowStage的事件订阅等。
  1. onForeground():应用进入前台时调用,可在此恢复在后台时暂停的操作,如重新申请在后台中释放的资源,准备应用的前台运行。
  2. onBackground():应用进入后台时调用,开发者可以在此释放一些暂时不需要的资源,或者执行一些后台任务,但要注意避免长时间阻塞,以免影响系统性能。
  3. onWindowStageDestroy():在UIAbility实例销毁之前,WindowStage销毁时调用,可以在此释放UI资源。
  4. onDestroy():应用销毁时触发,用于进行一些资源清理和数据保存的操作,比如关闭数据库连接、保存用户未保存的数据等。

页面生命周期:

  • 概念:主要针对@Entry修饰的组件,即页面。
  • 作用:帮助开发者更好地管理页面的显示和隐藏,以及处理页面间的跳转等情况,以提供更好的用户体验。
  • 具体函数:
  1. **aboutToAppear():**页面即将显示时调用,可在此进行一些页面显示前的准备工作,如加载页面数据、初始化页面组件等。
  2. aboutToDisappear():页面即将隐藏时调用,用于进行一些清理操作,如取消页面中的定时器、保存页面临时数据等。
  3. **onPageShow():**页面每次显示时触发一次,包括路由过程、应用进入前台等场景,可在此更新页面的状态或执行一些与页面显示相关的逻辑。
  4. onPageHide():页面隐藏时触发,可用于暂停页面中的一些动画或操作,以节省资源。
  5. onBackPress():当用户点击返回按钮时触发,可在此处理返回操作,如确认是否保存数据、是否允许返回等。

组件生命周期

  • 概念:自定义组件从创建到销毁或复用的过程。
  • 作用:使开发者能够在组件的不同阶段进行相应的操作,如初始化组件状态、释放组件资源等,有助于提高组件的可维护性和性能。
  • 具体函数:
  1. **aboutToAppear():**组件即将显示时调用,类似于页面的aboutToAppear,可用于组件的初始化操作。
  2. **aboutToDisappear():**组件即将隐藏时调用,用于清理组件相关资源。

29、使用过哪些第三方库?分别介绍一下

axios:⽤于处理HTTP请求的库,⽀持Promise。

lodash:提供实⽤⼯具函数的库,便于数据处理。

30、ForEach有几个参数?

forEach接受三个参数:当前元素、当前索引和原数组。

31、 api9 / api11 / api12 的区别?

  • 语法方面
    • API 9:在语法上相对较为宽松,支持函数表达式、展开运算符用于对象、赋值解构,也可以使用 var 关键字声明变量,声明变量时不强制要求定义类型。
    • API 11:与 API 9 相比,语法上有了一些变化和限制。函数表达式不再被支持,必须使用箭头函数;展开运算符仅支持数组;不再支持赋值解构;var 关键字不再被支持,必须使用 let 或 const 来声明变量;类型限制更为严格,声明变量时后面必须定义类型。
    • API 12:未在语法层面有与 API 11 较大差异的公开信息,但随着系统和开发环境的演进,可能存在一些细微调整或优化。
  • 系统兼容性方面
    • API 9:通常与 HarmonyOS 3.1 和 HarmonyOS 4.0 兼容。
    • API 11:可能与更新的 HarmonyOS 版本或 HarmonyOS Next 有更好的兼容性。由于 HarmonyOS Next 去除了 AOSP 兼容性,并且 SDK 版本之间没有直接的对应关系,开发者需要特别关注兼容性问题。
    • API 12:主要面向 HarmonyOS Next 版本,随着 HarmonyOS Next 的发展和完善,API 12 提供了更好的支持和适配,能充分利用 HarmonyOS Next 的新特性和优势。
  • 功能特性方面
    • API 9:具备基础的分布式系统能力、多种开发语言支持等鸿蒙系统的核心特性。
    • API 11:ArkUI 进一步完善组件能力和效果,如文本和容器类组件支持按字符截断、定制回车键行为等;增强了图形窗口的动效和窗口适配能力;应用框架增强了 Extension 能力,提供自动填充框架等;分布式软总线连接能力和规格进一步增强。
    • API 12:在多个模块都有显著的新增和改进功能。如 Ability Kit 新增支持 want 属性中 parameter 参数的更多描述信息;ArkUI 支持获取状态管理框架代理前的原始对象、通过 C-API 获取组件标识 ID 等;Camera Kit 新增一批 C-API 以完善相机能力;Device Security Kit 新增安全审计 API 等。
  • 安全与隐私方面
    • API 9:有基础的安全与隐私保护机制,为应用开发提供了一定的安全保障和隐私保护功能。
    • API 11:引入更严格的权限管理、更安全的数据存储和传输机制、以及更完善的用户隐私保护措施。
    • API 12:在 API 11 的基础上,可能进一步强化了安全与隐私方面的功能,例如 Device Security Kit 新增的安全审计 API,可获取窗口截屏事件、USB 插拔事件、剪切板复制粘贴事件等审计数据。

32、了解过多线程吗?和 Promise 区别是什么?

多线程允许同时执⾏多个线程,⽽Promise⽤于处理异步操作,单线程中管理操作顺序。

33、单层架构和三层架构区别?

结构复杂性

单层架构:单层架构的结构相对来说简单,因为它将所有的功能模块都集中在一块实现。这种架构适用于小型应用或原型开发。

三层架构:三层架构将整个系统划分为三个逻辑层面,每个层面负责不同的 业务,通过分层可以降低系统的耦合度,提高代码的可读性和可维护性。

可维护性

单层架构:单层架构一旦需要对某个功能进行改动,可能需要触及到整个应用的多个部分,

三层架构:三层架构每一层都可以独立地惊醒修改和扩展,不影响其他层次。

安全性

单层架构:单层架构,由于所有的功能都集中在一个地方,有可能导致安全漏洞更容易被利用。

三层架构:三层架构分层隔离了不同模块,安全性较高。

性能

单层架构:单层架构的性能比较受限,随着用户数量的增加,响应时间可能会边长,影响用户体验。

三层架构:三层架构可以通过负荷均衡和分布式处理来优化性能。例如,可以子啊前端使用内容分发网络(CDN)来加速静态资源的加载,在后端使用多个应用服务器来分担请求压力。

使用场景

单层架构:单层架构适用于简单的应用程序或原型开发,一般是项目规模较小,预算有限或时间紧迫时

三层架构:三层架构适用于大型企业级应用、高复杂度系统或需要长期维护和扩展的项目。

34、ArkTs和 其他前端的区别

语法:

ArkTS 是鸿蒙开发中使用的编程语言,基于 Type - Script 语法风格,具有强类型特性。它采用声明式编程来构建用户界面,通过组件和属性的组合描述 UI 状态。

Vue 也是声明式的 UI 框架,它的语法(template)基于 HTML 扩展来的。

Flutter 使用 Dart 语言,采用声明式编程构建 UI。它通过组合各种 Widget 来创建界面,

Dart 语言本身是面向对象的,语法上和 Type - Script、JavaScript 有一定差异,具有类型安全、高效的特点

跨平台能力:

ArkTS是主要专注于鸿蒙生态系统内的跨设备开发,分布式能力

Vue主要用于 Web 开发,在跨平台方面,相对来说没有 ArkTS。Flutter 那样原生的跨平台支持。

Flutter跨平台移动应用开发,可以使用一套代码构建出 iOS 和 Android 应用,并且在桌面端(如 Windows、Mac、Linux)也有一定的支持。但在非移动平台的生态整合方面可能不如 ArkTS 在鸿蒙生态系统中那样深入。

35、@Builder和@BuilderParam ,this指向

builder是用来定义或者抽UI结构,builderparam是用来应用builder这个UI结构的,如果想要在父组件重写UI结构,就可以使用builderparam来传递。

@builder自定义构建函数通常用于自定义一些重复使用的UI结构,而@builderParam则是用来引用,传递自定义的@builder结构,@builderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化

比方说在在子组件定义了一个custombuilder和一个customThisBuilder这两个自定义构建函数,并且定义了与之对应的@builderParam。然后子啊父组件定义一个componentBuilder。如果在父组件调用componentBuilder,那么this指定的就是父组件。

在自定义构建函数后面的括号传递块那可以使用

自定义组件

36、Http和axios的区别

鸿蒙原生http首先在性能和兼容性上比较有保障,原生API安全性方面,由于有鸿蒙系统的安全机制,在数据传输方面也是先天的优势。在资源占用这块也挺不错的,毕竟是系统原生的嘛,不会像引入那些第三方库似的,带来额外的资源开销,要是设备资源比较紧张,或者对性能要求挺高的场景,用它就挺合适的。

axios的话多了点功能,像请求和响应拦截器,在发请求前或者收到响应后,都能方便地做些预处理、处理错误或者转换数据之类的事儿,还能取消请求,自动把数据转成 JSON 格式呢,如果是http的话,这些功能就得自己手写了。还有axios 那个接口设计得比较简洁明了,http用起来就相对麻烦些。axios 是基于 JavaScript 的开源库,浏览器里能用,Node.js 环境里也能用,跨平台性比较好,http就只能在鸿蒙开发中使用。

37、蓝牙开发

问题 ------------你们项目中是如何基于鸿蒙系统跟穿戴设备进行通信的。

1.手环和手表都是低功耗蓝牙模块。都是采用ble来进行通信。所以项目在技术选型的数据才用鸿蒙next'中最新版本的ble模块来进行通信。

鸿蒙next针对蓝牙通信也提供很多模块。比如:人机接口模块、音乐模块

2.拿到蓝牙设备后,会先对设备进行通信测试。在手机或者pad中下载lightblue这个工具连接设备进行数据的传输和获取。查看设备的uuid等等。

当设备测试通信没有问题,才开始app中去数据交互

3.在项目中打开蓝牙(关闭蓝牙)

4.蓝牙通信会涉及权限,权限有两种类型。

系统蓝牙权限: 使用蓝牙、发现蓝牙,无需向用户申请权限。直接在项目module.ison5配置文件中设置

用户授权: ACCESS BLUETOOTH,这个权限用户级别,必须在代码中先检测用户是否授权。没有授权弹框出来让用户点击授权确认。

请求用户授权API:atManager.requestPermissionfromuser

5.开启扫描和关闭扫描

因为我们用户ble模块,扫描10米以内低功蓝牙设备。如果硬件设备没有问题。扫描到了。判断rssi(无线信号强度指标)强度,规定-100以内都属于可连接。-50属于比较强信号

判断设备是否有名字。当满足这个条件后,将扫描到蓝牙设备保存起来。渲染给用户,用户点击链接

  1. 连接设备:用户点击链接设备,就需要用到蓝牙的mac地址。通过这个mac地址结合GattClientDevice对象来链接设备。一旦链接上需要输入验证码。
  2. 获取服务:连接上蓝牙过后,通过getService接口获取蓝牙提供服务。返回seviceuuid,这个服务唯一值,获取到这个服务,才能后续发送数据和接受数据,传递那个uuid给设备。8. 接受蓝牙数据:

蓝牙设备会持续传递数据给app,所以我们采用监听需要我们传递服务对象提供参数。

9给设备发送数据:

先获取service服务对象,得到uuid值。

调用writeCharacteristicValue,必须传递二进制数据。一般都是创建ArrayBuffer对象,将数据存放二进制缓冲区。发送给蓝牙设备。

38、camera相机服务

拍照

  1. 导入image接口。创建拍照输出流的SurfaceId以及拍照输出的数据。
  2. 创建拍照输出流。

通过CameraOutputCapability类中的photoProfiles属性,可以获取当前设备支持的拍照输出流,通过createPhotoOutput方法传入支持的某一个输出流及步骤一获取的SurfaceId创建拍照输出流。

  1. 设置拍照photoAvailable的回调,并将拍照的buffer保存为图片。

使用安全控件创建一张图片资源为例

设置安全控件按钮属性。

创建安全控件按钮。

调用MediaAssetChangeRequest.createImageAssetRequestPhotoAccessHelper.applyChanges接口创建图片资源。)

4.配置相机的参数可以调整拍照的一些功能,包括闪光灯、变焦、焦距等。

5.触发拍照。

通过photoOutput类的capture方法,执行拍照任务。该方法有两个参数,第一个参数为拍照设置参数的setting,setting中可以设置照片的质量和旋转角度,第二参数为回调函数。

获取拍照旋转角度的方法为,通过PhotoOutput类中的getPhotoRotation方法获取rotation实际的值

39、在鸿蒙开发中,OCR(Optical Character Recognition,光学字符识别)的使用步骤和作用如下:

使用步骤

  1. 项目初始化与权限配置:在config.json文件中添加必要的权限,如ohos.permission.INTERNET,确保应用拥有网络访问权限等。

  2. 引入相关模块:在代码中导入CoreVisionKit中的textRecognition模块等相关模块。例如:import { textRecognition } from '@kit.CoreVisionKit';。

初始化 Text Recognition 服务:在应用相关生命周期方法中,如aboutToAppear函数中初始化

  1. 文字识别服务。获取待识别的图像:可以通过多种方式获取图像,如从相册选取或使用相机拍摄。

  2. 从相册获取:借助CoreFileKit中的picker来打开相册选择图片,并获取图片的 URI。

  3. 相机拍摄:利用Camera Kit来实现相机拍照功能,获取拍摄的图片。

  4. 将图像转换为 PixelMap:通过ImageKit等相关工具将获取到的图片资源转换为PixelMap格式,因为VisionInfo目前仅支持PixelMap类型的视觉信息。

  5. 实例化 VisionInfo 对象:将待检测图片的PixelMap传入VisionInfo。

  6. 配置通用文本识别的配置项:TextRecognitionConfiguration用于配置是否支持朝向检测等参数。

  7. 调用识别接口:调用textRecognition的recognizeText接口进行文字识别,并处理识别结果。

  8. 释放 OCR 服务资源:在应用不再需要使用 OCR 服务时,如aboutToDisappear函数中,释放 OCR 服务资源,以避免资源占用。

40、为什么要使用双Token?双Token如何实现?

  1. 产品需求:既要保护后台数据和用户信息的安全,也要提高用户与产品的耦合度。
  2. 解决方案:使用双Token策略

① 跟后端协定好,用户成功登录后后台给我们返回 Token,refreshToken 两个Token,其中 Token 是用来真正获取数据的,可以设置短周期,比如8个小时(跟后端协商)。而 refreshToken 是用来更新 Token 的,可以设置长周期,比如1~3天(跟后端协商)。

② 普通请求时,携带 Token 且 Token 未过期,则请求正常返回。

③ Token 过期,但refreshToken没有过期,根据返回的状态码401 调用延长Token 失效的接口 并传入refreshToken 重新获取新的Token和refreshToken,并更新保存下来。

3.衍生问题:Token失效时refreshToken未失效,但是用户是不知道的,当用户点击新的页面是调用接口后台会发现token失效,则不会返回数据,虽然调用了延长 Token 接口返回并新的Token,但是此时页面是没有数据的,用户的体验感会很差。

解决方案:无感请求处理

所以需要继续调用用户所访问页面的接口,并传入更新好的 Token 重新拿到数据,渲染数据展示给用户,这样用户就会觉得自己一直处于登录的状态

④ Token 过期调用延长Token失效的接口,如果refreshToken 也过期,返回的状态码都是401 就会无限调用延长Token失效的接口,所以需要做判断,发现两个Token都失效时则立即拦截,让用户返回登录页。

41、监听数据变化,可以使用什么装饰器?

可以使用@watch装饰器来监听数据的变化,@watch必须配合其他装饰器(比如@State,@Prop,@Link等)一起使用。

使用方法:

@State

@Watch('回调函数名')

info:string=''

回调函数名(){

}

42、首选项通过什么方式存储?存在什么地方?

存储形式:首选项(Preferences)通过键值对(Key-Value)的形式储存数据,用于为应用提供轻量级的数据处理能力,并支持数据的持久化储存

存储位置:默认储存位置为该应用的应用沙箱中

43、axios的原理,以及用法?

Axios是一个基于promise的http客户端,用于在浏览器和Node.js中发送http请求。

其工作原理主要包括以下几个方面:创建请求配置对象:包含请求的方法(如GET、POST等)、URL、请求头、请求体等消息。利用XMLHttpRequest对象或浏览器的fetch发送请求。处理请求的响应:包括解析响应数据、处理错误状态等,返回一个Primose对象,以便惊醒异步操作的处理和链式调用用法。

44、router如何进行页面传值?

使用router中的params属性进行传值,

在跳转页面是使用

aboutToAppear(){

const res = router.getparams()}

进行接收完成页面传值。

45、线程的两种方式有什么区别?

在鸿蒙(HarmonyOS)中,实现多线程的主要有两种方式:线程和协程,协程更轻量,适合高实时性需求:线程更独立,适合复杂并发操作。

46、http是在主线程内还是另起一个线程?

Http请求通常在主线程中发起,但现代编程环境多采用异步方式处理,避免堵塞主线程,从而影响应用的响应速度。

为了避免这种情况,通常建议在子线程或通过异步任务(如async,Promise等)来执行网络请求,以确保主线程的流畅性。

47、Promise异步、和tasktool有什么区别吗

简言之,promise适合处理异步操作的结果,而TaskPool更适合管理大量并发任务。

48、多线程改变了主线程的值 那么主线程内的值会不会一起改变?

在多线程环境中,一个线程对共享变量的修改是否能被其他线程(包括主线程)看到,取决于以下几个方面:

1.内存可见性:确保线程之间的修改能够相互可见。

2.同步机制:确保线程之间的正确通信。

49、什么时候调用自定义 Loading?

通常在以下情况下调用自定义 Loading 组件:

  • 数据请求时:当应用需要从网络或本地存储获取数据时,为了给用户提供良好的交互体验,在请求开始时显示 Loading 组件,请求完成后隐藏。

  • 数据提交时:当用户提交表单或执行其他需要较长时间处理的操作时,显示 Loading 组件,直到操作完成。

  • 页面加载时:在页面初始化需要进行大量数据处理或资源加载时,显示 Loading 组件。

50、 获取数据的时候调用 Loading,提交数据的时候用 Loading,都是用 Loading 组件吗?Loading 组件放在哪里?放到全局还是放到哪里?

获取数据和提交数据时都可以使用同一个 Loading 组件。Loading 组件的放置位置取决于具体的业务需求:

  • **全局 Loading**:如果多个页面或组件都需要使用 Loading 组件,可以将其封装为全局组件。可以在应用的根组件中添加 Loading 组件,并通过状态管理来控制其显示和隐藏。

  • **局部 Loading**:如果某个页面或组件只在特定的操作中需要显示 Loading,可以将 Loading 组件添加到该页面或组件中。

51、stage 模型和 FA 模型的区别?

  • **FA(Feature Ability)模型**:

  • 是鸿蒙早期的应用开发模型,基于 Ability 和 AbilitySlice 构建。

  • 主要使用 Java 或 JavaScript 进行开发。

  • 应用的配置信息存储在 `config.json` 文件中。

  • **Stage 模型**:

  • 是鸿蒙 3.1 及以上版本推荐的应用开发模型,更加简洁和灵活。

  • 支持使用 Java、Kotlin 和 JavaScript 进行开发。

  • 应用的配置信息存储在 `module.json5` 文件中,采用模块化的配置方式。

  • 引入了 Page Ability 和 Service Ability 的概念,简化了开发流程。

52、平时怎么找到自己打印的 log?

在鸿蒙开发中,可以通过以下方法找到自己打印的 log:

  • **DevEco Studio 日志窗口**:在 DevEco Studio 中,打开 `Logcat` 窗口,通过设置过滤条件,如包名、日志级别等,来筛选出自己打印的 log。

  • **日志标签**:在打印 log 时,可以使用自定义的标签,在 `Logcat` 窗口中通过标签进行过滤,快速定位自己的 log。例如:

```typescript

import logger from '@system.logger';

const TAG = 'MyAppLog';

logger.info(TAG, 'This is a custom log message.');

```

在 `Logcat` 窗口中设置过滤条件为 `MyAppLog`,即可快速找到该日志信息。

53、了解过V2吗?v1与v2区别?

  • 数据观察能力
    • V1:@Observed 可观察第一层的属性,需要搭配 @ObjectLink 使用才能生效。
    • V2:@ObservedV2 本身无观察能力,仅代表当前 class 可被观察,如果要观察其属性,需要搭配 @Trace 使用,@Trace 装饰的属性可以被精确跟踪观察。
  • 组件装饰器
    • V1:使用 @Component 作为搭配状态变量的自定义组件装饰器。
    • V2:使用 @ComponentV2 作为搭配状态变量的自定义组件装饰器。
  • 状态变量初始化
    • V1:@State 和 @Local 类似都是数据源的概念,在不需要外部传入初始化时,可直接迁移。如果需要外部传入初始化,则可以迁移为 @Param@Once。
    • V2:@Local 必须在组件内部初始化,可初始化子组件中 @Param 装饰的变量;@Param 可本地初始化,但不允许再次改动,若本地不初始化,则与 @Require 装饰器一起用,必须父组件初始化,可以接受任意类型的数据源,包括普通变量、状态变量、常量、函数返回值等,还可初始化子组件中 @Param 装饰的变量。
  • 数据同步与更新
    • V1:@Link 是框架自己封装实现的双向同步1。@Prop 和 @Param 类似都是自定义组件参数的概念,当输入参数为复杂类型时,@Prop 为深拷贝,@Param 为引用1。
    • V2:对于 V2 开发者可以通过 @Param@Event 自己实现双向同步1。@Param 支持父子单向同步(但更改对象属性会同步)5。
  • 状态监听
    • V1:@Watch 用于监听状态变量的变化,具有监听状态变量本身和其第一层属性变化的能力。
    • V2:@Monitor 用于监听 V2 状态变量的变化,搭配 @Trace 使用,可有深层监听的能力。状态变量在一次事件中多次变化时,仅会以最终的结果判断是否触发 @Monitor 监听事件。

性能优化4

  • V1:状态管理在频繁的状态变更时,可能会触发过多的 UI 渲染,影响应用的性能。
  • V2:引入了更智能的状态更新机制,减少了不必要的 UI 渲染,只有实际依赖该状态的组件才会更新,优化了性能;提供了批量更新的机制,减少了单个状态更新造成的多次渲染。

开发体验4

  • V1:状态管理的操作较为基础,尤其是在跨组件共享状态时,需要较多的手动管理。
  • V2:提供了更加丰富的状态装饰器(如 @ProvideGlobal、@ConsumeGlobal),让开发者能更灵活地管理全局状态,减少手动代码编写;改进了双向数据绑定机制,减少了状态不一致的问题。

更详细看官网

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-v1-v2-migration-V5

54、怎么实现华为登录?

前期准备:( cer、 csr、 p12、 p7b )

1.获取证书和签名,DevEco Studio 工具侧生成密钥(.p12)

和证书请求文件(.csr)--构建中生成私钥和证书文件;

在AGC平台中生成p7b和cer文件;

(申请华为登录得服务-管理中心-权限管理)

2.DevEco配置权限,module.json5中配置client_id

AppScope/app.json5 -> 检查 bundleName

让后端准备的华为授权接口

3.进行scope权限申请实现华为登录的过程就是:调用授权API向华为服务器申请获取Code,返回code后,再将其发送应用服务器进行解析,解析出一个手机号返回。

编码实现;

1.我封装了一个华为授权登录得工具类,包含申请授权登录和取消授权登录。

2.在页面中调用申请授权登录,获取code

3.把code发送给后端服务器,后端服务器向华为服务器获取用户信息,后端完成校验后,创建账号或返回账号信息(需后端提供接口)

4、把账号信息根token保存起来,完成登录。

5.退出登录时,清理授权信息。

55、图案密码锁用的是什么?

1.图案密码锁的特点

输入方式: 用户通过手指在图案密码锁组件的格子区域滑动,连接特定顺序的格子来创建密码。

验证机制: 当用户再次按照相同的顺序连接格子时,系统会根据输入的顺序与预设的密码进行比对,以验证用户的身份。

界面表现: 图案密码锁组件通常会以图形化的方式展示格子,并在用户选择格子时显示选中的状态(如颜 色变化)

2.在DevEco中的实现

组件支持:从HarmonyOS的某个版本(如APIVersion 9开始)起,DevEco Studio支持图案密码锁组件的开发。

属性与事件:图案密码锁组件提供了一系列属性和事件,用于自定义组件的外观和行为。例如,可以设置格子的大小、颜色、边框宽度等属性,以及监听密码输入完成等事件。

开发文档与示例:DevEco Studio提供了详细的开发文档和示例代码,帮助开发者快速上手并实现图案密码锁功能。开发者可以参考这些资源来了解组件的详细用法和最佳实践。

56、鸿蒙开发的四大特性

分布式能力:跨设备协同:鸿蒙系统能够打破设备之间的壁垒,让不同的智能设备可以无缝地协同工作。

元服务:免安装,轻量化,快捷。

一次开发,多端部署:就是代码复用;鸿蒙开发框架支持使用一套代码,适配多种不同类型的设备终端。

硬件级安全:隐私保护机制,例如,用户可以设置相机应用只有在打开应用拍照时才能访问摄像头,

57、滚动嵌套处理方法

Scroll嵌套List的时候,如果List默认不设置高度是会默认全部展开的,可以实现Scroll滚动整个布局的效果,但是这样会失去懒加载效果,可以使用List组件的nestedScroll属性来实现嵌套滚动效果

向前滚动:父级优先

向后滚动:自身优先

58、拦截器

请求拦截器interceptors.request.use

可以在这里获取一下token,把token拼接在请求头,

响应拦截器interceptors.response.use

在这里主要是处理返回的错误码,400一般是参数错误,401是token信息错误

59、git如何管理一个项目?

1.是什么

git是一个分布式版本控制工具

2.常见的命令

1.git clone将远程仓库的项目资料下载下来

2.git checkout -b dev(dev 为本地分支名)

3.git add .将工作区文件存在暂存区

4.git commit -m""从暂存区存到仓储区

5.使用git push将其上传到远程仓库,推送之前先pull一下

60、Git如何解决合并冲突?

1.冲突的原因

不同分支,不同代码,相同位置就会产出合并冲突问题

2.解决办法

2.1.如果是双方的代码是不同的业务,那就保留双方双方更改(vscode有提示)

2.2.如果是重复的业务逻辑,那就选择采用当前更改(vscode有提示)

关联知识点=>开发中如何避免冲突

100%避免git冲突是不可能的,但可以尽可能避免解决冲突

1.可以'少量多次' 提交

2.提交代码之前,先pull-下

3.保持团队良好沟通,协同开发,及时同步信息

61、正在A分支开发,但是有紧急需求需要在B分支处理,此时A分支代码没有开发完整,又不能提交代码,这个时候暂存本地代码,怎么做

1.git stash 暂存当前所有的修改

2.git stash save'备注内容

3.git stash pop 应用最近的一次stash并删除

62、git merge 和 git rebase的区别

1.是什么

git rebase 与 git merge 解决了相同的问题, 都是将一个分支的提交合并到另一分支上

2.区别

rebase会改变提交历史;merge则会保留真实的历史

merge 是一个合并操作,会将两个分支的修改合并在一起,默认操作的情况下会提交合并中修改的内容·merge 的提交历史记录了实际发生过什么,关注点在真实的提交历史上面

rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面

rebase 操作会丢弃当前分支已提交的 commit,故不要在已经 push 到远程,和其他人正在协作开发的分支上执行 rebase 操作

merge 与 rebase 都是很好的分支合并命令,没有好坏之分,使用哪一个应由团队的实际开发需求及场景决定

相关推荐
MiyueFE16 分钟前
bpmn-js 源码篇8:Featrues 体验优化与功能扩展(三)
前端·javascript
中科三方21 分钟前
什么是权威解析服务器?权威解析服务器有什么用?(国科云)
服务器·git·github
GP9_小怪兽1 小时前
deepseek流数据开发环境可以分批次接收 到服务器上返回的是流但数据一次就返回了
服务器
dchen771 小时前
xhr和fetch的一些区别对比
前端·javascript·面试
徐小夕1 小时前
耗资100小时,我开源了一款PPT在线编辑器
前端·javascript·github
Vae_Mars1 小时前
uniapp中props的用法
前端·javascript·uni-app
百事可乐☆1 小时前
vue 对接 paypal 订阅和支付
前端·javascript·vue.js
SUN14862011818801 小时前
JavaScript编码规范
javascript·代码规范
ChinaDragonDreamer1 小时前
HarmonyOS:通过键值型数据库实现数据持久化
harmonyos·鸿蒙