2024鸿蒙开发【面试题库】,转岗看这一篇就够了

鸿蒙面试浪潮来袭,你是否也想着利用这次机会去实现,跳槽涨薪的梦呢?

如果关注了华为鸿蒙的人应该知道:鸿蒙开发岗位需求飙升6倍! 可想而知该岗位前景多么广阔,为此就为大家整理些(鸿蒙HarmonyOS)开发岗位面试题。

面试题目

以下问题是在面试过程中实际遇到的

1. 页面和组件的生命周期,及其流程

1

2. @Entry 装饰的页面和 Navigation 组件里的页面,有什么区别
  • @Entry 装饰的页面
  • 定义:是一个基本的页面,每一个页面都需要在 main_page.json 中声明
  • 路由:这种页面是路由的起点,通常用于展示应用的入口
  • 生命周期:具有通用的生命周期方法,如 @Entry 修饰的页面中的通用方法
  • Navigation 组件
  • 定义:是一个导航容器,挂载在单个页面下
  • 路由:支持跨模块的动态路由,通过自定义路由表或系统路由表实现页面的跳转
  • 页面结构:由标题栏、内容区和工具栏组成,支持页面的路由能力和多种显示模式
  • 显示模式:可以设置为单页显示或分栏显示模式,适应不同设备尺寸
3. 常用的状态装饰器有哪些
分类内容
管理组件拥有的状态
@State装饰器组件内状态
@Prop装饰器父子单向同步
@Link装饰器父子双向同步
@Provide装饰器和@Consume装饰器与后代组件双向同步
@Observed装饰器和@ObjectLink装饰器嵌套类对象属性性变化
一般回答上面这几个就够了
管理应用拥有的状态
LocalStorage页面级UI状态存储
AppStorage应用全局的UI状态存储
PersistentStorage持久化存储UI状态
其他状态管理
@Watch装饰器状态变量更改通知
$$语法内置组件双向同步
@Track装饰器class对象属性级更新
4. 常用的动画有哪些
  • 一、组件的属性动画
  • 二、页面间的转场动画
  • 三、lolita 库加载动画资源文件
5. ArkTs 和 Ts 有什么区别

ArkTs 基于 Ts 做了扩展,并且强化了静态检查和分析

  • 一、扩展了 UI:
  1. 定义了声明式 UI 描述、自定义组件,事件方法、属性方法
  2. 提供了多维度的状态管理机制
  3. 提供了控制渲染、循环渲染的能力
  • 二、强化了检查
  1. 不支持 var、any、unknown、Symbol
  2. 不支持解构赋值
  3. 不支持使用对象字面量进行类型声明
  4. 不支持在运行时动态增删对象的属性
  5. 不支持在函数内声明函数
  6. 不支持使用 typeof 作为类型
  7. 不支持使用 # 符号开头声明的私有字段,改用 private 关键字
  8. 不支持把 function 定义函数赋值给变量,改为使用箭头函数
6. 动态 import 加载模块,以及反射
// Calc.ets 
export class Calc { 
  public constructor() {} 
 
  public static staticAdd(a: number, b: number): number { 
    return a + b;  
  } 
 
  public instanceAdd(a: number, b: number): number { 
    return a + b; 
  } 
} 
 
export function addHarLibrary(a: number, b: number): number { 
  return a + b; 
} 
 
// index.ets 
let harLibrary = 'harlibrary'

// 动态import变量是新增特性,入参换成字符串'harlibrary'是现有特性。也可使用await import方式
import(harLibrary).then((ns: ESObject) => { 

  // 反射调用静态成员函数staticAdd() 
  ns.Calc.staticAdd(7, 8); 
  
  // 实例化类Calc 
  let calc: ESObject = new ns.Calc(); 
  
  // 调用实例成员函数instanceAdd() 
  calc.instanceAdd(8, 9); 
  
  // 调用全局方法addHarLibrary() 
  ns.addHarLibrary(6, 7); 
})
7. 如何做沉浸式状态栏

暂略,后续补充

8. 如何实现垂直的三栏布局

即:顶部显示标题,底部显示按钮,中间没有内容,但需要占满剩余空间

  • 以下三种方式都行:
  • Blank 组件
  • Column 组件 + layoutWeight()
  • Flex 组件
9. @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)
  }
10. 如何实现给父组件传递子组件
  • 使用 @BuilderParam
  • 以下示例代码是我个人开发中该组件的简化版
@Component
export struct Visible {
  @Prop isShow: boolean = true
  @BuilderParam children: () => void = this.EmptyBuilder

  @Builder
  EmptyBuilder() {
  }

  build() {
    Column() {
      this.children()
    }
    .visibility(this.isShow ? Visibility.Visible : Visibility.Hidden)
  }
}

// 使用
Visible({ isShow: true }) {
  Tech()
}

可能的面试题目

以下问题是我个人感觉可能被问到的

1. 使用router.back() 方法返回到原来的页面,会触发原页面的 aboutToAppear() 生命周期回调吗,会触发哪个生命周期?

不会触发 aboutToAppear,但是会触发 onPageShow()

2. UIAbility 和 WindowStage 的生命周期,及其流程

2

3. Model 分为几种类型,分别是什么

3

4. Hap、Har、Hsp 分别是什么,它的特点及其应用场景

这三个都是 HarmonyOS 中的三种不同类型的构建产物,它们在鸿蒙系统中有着不同的作用和特点

  1. Hap
  • 通过 entry 和 feature 类型的 Model 构建来的
  • 可以被单独安装和运行
  1. Har
  • 通过 Static Library 类型的 Model 构建来的
  • 编译时会被打包进使用到它 Hap/Hsp 包中
  • 多包引用相同的 Har 包时,会造成多包间代码和资源的重复
  1. Hsp
  • 通过 Shared Library 类型的 Model 构建来的
  • 不会被打包进使用它的 Hap/Hsp 包,而是单独存在
  • 当多包需要同时引用同一个共享包时,可以采用 Hsp 替代 Har,能避免 Har 造成的多包间代码和资源的重复拷贝,从而减小应用包大小

4

5. 简单说下开发阶段、编译阶段、发布阶段的包结构

不建议直接问这个,求职者很难用文字描述来回答 5
6

6. 什么是应用模型

应用模型是系统为开发者提供的,开发应用程序必备的组件和运行机制。 有了应用模型,开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效

  1. 应用组件: 是应用的基本单元和运行入口。 用户使用应用时,应用组件会在不同的状态间切换,这些状态称为组件的生命周期。 开发者需要编写组件及其生命周期的回调函数,并在配置文件中进行相关配置。
  2. 应用进程模型: 定义了应用进程的创建和销毁方式,以及进程间的通信方式。
  3. 应用线程模型: 规定了进程内线程的创建和销毁方式,以及主线程和UI线程的创建方式和通信方式。
  4. 应用任务管理模型(仅对系统应用开放): 定义了任务的创建和销毁方式,以及任务与组件的关系。 任务是用户使用应用组件实例的记录。例如,在使用视频应用时,会生成一个视频应用任务,如果启动视频编辑功能,会生成一个视频编辑任务。
  5. 应用配置文件: 包含应用的配置信息、组件信息、权限信息及开发者自定义信息。 这些信息在编译、分发和运行阶段提供给相应的工具和系统使用。
7. 简单解释下 Stage 模型
  • Stage模型是 HarmonyOS 从 API 9开始为开发者新提供的一种应用模型,会是以后主推的模型
  • 它的特点是:
  1. 多个应用组件可以共享同一个ArkTS引擎实例 。这意味着应用组件之间可以方便地共享对象和状态,同时减少内存占用
  2. Stage模型提供了丰富的生命周期回调函数,开发者可以通过这些回调感知应用的状态变化
  3. Stage模型采用面向对象的方式,将应用组件以类接口的形式开放给开发者,可以进行派生,利于扩展能力
  • 它包含:
  1. UIAbility 组件 (用于和用户交互)
  2. ExtensionAbility 组件 (提供特定场景(如卡片、输入法)的扩展能力)
8. 限定词目录匹配的优先级

移动国家码和移动网络码 > 区域(可选组合:语言、语言_文字、语言_国家或地区、语言_文字_国家或地区)> 横竖屏 > 设备类型 > 颜色模式 > 屏幕密度

9. Reusable 是什么
  • @Reusable 装饰器装饰的自定义组件,具备运行时可复用的能力
  • 这类组件被卸载后,会放在复用缓存里,当再次需要这类组件时,会从缓存中找到,可以对它更新数据后直接添加到组件树中,节省了创建组件节点的时间
  • 一般是优化具有大量数据的列表,在快速滚动时的性能时使用,频繁创建和销毁列表项可能导致卡顿和掉帧问题,重用已经创建的列表项视图,可以提高滚动的流畅度
10. 为什么应该避免,在视图里直接改变状态变量,如图所示

7

8

  • API 9 以后的版本,UI 是以组件为单位更新的,组件上某个属性发生改变时,会更新这个组件整体
  • 被状态变量改变影响到的组件,才会发生更新,其它组件不会更新
  • 以上代码中,Text 组件的更新,只会发生在 col1 改变后,不会发生在 col2 改变后,因为它没有使用到 col2,所以不会发生更新
11. build() 函数内的语法需要遵守什么限制
  1. @Entry装饰的自定义组件,其 build() 函数下的根节点唯一且必要,且必须为容器组件
  2. @Component装饰的自定义组件,其 build() 函数下的根节点唯一且必要,可以为非容器组件
  3. ForEach 禁止作为根节点
  4. 不允许使用 switch 语法
  5. 避免直接在 Text 组件内改变 count 的值
  6. 不允许调用没有用 @Builder 装饰的方法
  7. 不允许声明本地变量
  8. 不允许创建本地作用域
  9. 不允许 console.info 之类的语句
12. web 和原生组件通信
import { webview } from '@kit.ArkWeb'

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController()
  
  build() {
    Column() {
      // 三种加载网页的方式
      Web({ src: $rawfile("index.html"), controller: this.controller })
      Web({ src: "resource://rawfile/index.html", controller: this.controller })
      Web({ src: 'www.example.com', controller: this.controller })
      .zoomAccess(false)
      .aspectRatio(1)
      .javaScriptAccess(true)
      .onPageEnd(async e => {
         // 调用网页内函数并获取返回值
         const res = await this.controller.runJavaScript('test()')
       })
       // 页面上调用 confirm() 函数时触发,以此来实现页面向原生通信
      .onConfirm(event => {
         
      })
    }
  }
}


// module.json5 访问网络前需要申请网络权限
"module": {
    "requestPermissions": [
         {"name": "ohos.permission.INTERNET"}
     ]
 }
13. 持久化存储
preference: preferences.Preferences

this.preference = preferences.getPreferences(getContext(this), 'my-preference')

// 读取,异步的方法,也有 getSync 这样同步的方法
const res = await this.preference.get(key, defaultValue)

// 写入
this.preference.put('accountInfo', response)

// 写到文件
this.preference.flush()

// 清空
this.preference.clear()
14. Worker

Worker 能创建独立线程,一般用来处理一些比较耗时的操作,避免在大量计算时阻塞主线程的运行 Worker 线程不支持UI操作 Worker 线程一旦被创建则不会主动被销毁,在一定程度上会造成资源的浪费,应及时关闭空闲的 Worker 创建Worker的线程称之为宿主线程,Worker自身的线程称之为Worker线程。创建Worker传入的url文件在Worker线程中执行,

import { worker } from '@kit.ArkTS'

// 主要说明以下两种场景:

const workerStageModel01 = new worker.ThreadWorker('entry/ets/workers/worker.ets', {name:"first worker in Stage model"});

const workerStageModel02 = new worker.ThreadWorker('phone/ets/ThreadFile/workers/worker.ets');

// 向宿主线程发送消息
workerStageModel02.postMessage()
14. Worker 和 TaskPool 的区别

9

重点放最后

随着鸿蒙5.0的推出,市场上的鸿蒙开发岗位也随之增加;许多程序员开始面向鸿蒙岗位,但是网上的面试题几乎看不到。

作为最早一批学鸿蒙开发的我,整理了自己以及开发群友面试所问到的题目。
3

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值