HarmonyOS应用开发者高级认证题目(7月新版,答案&解析,持续更新)

单选

1.ArkTS支持以下哪些函数
A.Object.getOwnPropertySymbols();
B.Object.isExtensible();
C.Object.isPrototypeOf();
D.Object.keys();

答案:D

2.在方舟字节码的函数调用规范中,前三个参数表示的含义分别是
A.new.Targetthis、函数对象本身
B.new.Target、函数对象本身、this
C.this、函数对象本身、new.Target
D.函数对象本身、new.Targetthis

答案:D。在方舟字节码的函数调用规范中,前三个参数表示的含义分别是函数对象本身、new.Targetthis

3.以下哪些赋值语句在ArkTS中是合法。

class A {
  v: number = 0;
}
class B extends A {
  u: string = '';
}

class C {
  v: number = 0;
}
let a1: A = new C();
let a2: A = new B();
let a3: B = new A();
let a4: C = new B();

解析:

A选项中,C类的实例不能赋值给A类型的变量,因为C类没有继承自A类,所以let a1: A = new C();是不合法的。

B选项中,B类继承自A类,所以let a2: A = new B();是合法的。

C选项中,A类的实例不能赋值给B类型的变量,因为B类具有额外的属性u,所以let a3: B = new A();是不合法的。

D选项中,B类的实例不能赋值给C类型的变量,因为C类没有B类的属性u,所以let a4: C = new B();是不合法的。

综上所述,合法的赋值语句是let a2: A = new B();,答案为B。

4.以下关于**TaskpoolWorker**的描述正确的是
A.TaskPoolWorker的任务执行时长上限都是无限制
B.Worker自行管理生命周期,开发者无需关心任务负载高低
C.开发者需要自行管理taskpool的数量及生命周期
D.TaskPool支持任务延时执行

解析:D。TaskPool支持任务延时执行,A选项中TaskPool和Worker的任务执行时长通常是有限制的;B选项中Worker的任务负载情况需要开发者关注;C选项中开发者通常不需要自行管理taskpool的数量及生命周期。

5.以下哪个装饰器用来表示并发共享对象。
A.@Sendable
B.@Style
C.@State
D.@Shared

解析:A。@Sendable装饰器用来表示并发共享对象。

6.从桌面冷启动如下应用代码,点击Change按钮5次,整个过程中,代码中的2条log依次出现的次数是:

class Data {
  num: number
  type: string

  constructor(num: number, type: string) {
    this.num = num;
    this.type = type;
  }
}

@Reusable
@Component
struct Item {
  @State data: Data | undefined = undefined;

  aboutToAppear(): void {
    console.log("Demo log1");
  }

  aboutToReuse(params: ESObject): void {
    console.log("Demo log2");
    this.data = params.data
  }

  build() {
    Text("num = " + this.data?.num + ", type = " + this.data?.type)
  }
}

@Entry
@Component
struct Index {
  data1: Data = new Data(1, "type1");
  data2: Data = new Data(2, "type2");
  @State data: Data = this.data1

  build() {
    Column() {
      if (this.data.type == "type1") {
        Item({ data: this.data }).reuseId(this.data.type)
      } else {
        Item({ data: this.data }).reuseId(this.data.type)
      }
      Button('Change').onClick(() => {
        if (this.data === this.data1) {
          this.data = this.data2
        } else {
          this.data = this.data1
        }
      })
    }
  }
}

解析:点击Change按钮5次,会导致Item组件的复用。每次复用会触发aboutToReuse函数,输出“Demo log2”。

初始时,创建Item组件会触发aboutToAppear函数,输出“Demo log1”。

之后每次点击Change按钮,都会导致Item组件的复用,输出“Demo log2”。

所以,“Demo log1”出现1次,“Demo log2”出现5次。

答案为:C。

7.以下关于ArkUI NavDestination组件的生命周期执行顺序中正确的
A.onWillappear->onAppear->onWillShow->onShow->onWillHide->onHidden->onWillDisappear->onDisappear

B.onWillappear->onAppear->onWillShow->onShow->onWillHide->onWillDisappear->onHidden->onDisappear

C.onWillappear->onWillShow->onShow->onAppear->onWillHide->onHidden->onWillDisappear->onDisappear

D.onWillappear->onAppear->onWillShow->onShow->onWillDisappear->onWillHide->onHidden->onDisappear

解析:A。ArkUI NavDestination组件的生命周期执行顺序为:onWillappear->onAppear->onWillShow->onShow->onWillHide->onHidden->onWillDisappear->onDisappear

8.依次点击A、B、C、D四个按钮,其中不会触发UI刷新的是:

class Info {
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}
@Entry
@Component
struct Index {
  @State nameList: Info[] = [new Info("Tom"), new Info("Bob"), new Info("John")]

  build() {
    Column() {
      ForEach(this.nameList, (item: Info) => {
        Text(`${item.name}`)
      })
      Button("A")
        .onClick(() => {
          this.nameList.push(new Info("Lucy"));
        })
      Button("B")
        .onClick(() => {
          this.nameList[0] = new Info("Eric");

        })
      Button("C")
        .onClick(() => {
          this.nameList[0].name = "Jim";
        })
      Button("D")
        .onClick(() => {
          this.nameList = [new Info("Barry"), new Info("Cindy"), new Info("David")];
        })
    }
  }
}

解析:C选项不会触发UI刷新。在A选项中,通过push操作向数组添加新元素,会触发UI刷新。在B选项中,修改数组元素的值,会触发UI刷新。在D选项中,直接重新赋值数组,会触发UI刷新。而在C选项中,只是修改了数组中第一个元素的name属性,不会导致数组的引用发生变化,因此不会触发UI刷新。
所以答案是C。

9.以下哪份代码可以实现下图Grid布局
(图略)

A.通过设置不同GridItem的宽度

// xxx.ets
@Entry
@Component
struct GridExample3 {
  numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  scroller: Scroller = new Scroller()
  columnGap: number = 10
  gridItemWidth: number = 80

  build() {
    Column({ space: 5 }) {
      Grid(this.scroller) {
        ForEach(this.numbers, (day: string) => {
          if (day === '0' || day === '5') {
            GridItem() {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width(this.gridItemWidth * 4 + this.columnGap * 3)
                .height(80)
                .textAlign(TextAlign.Center)
            }
          } else {
            GridItem() {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width(this.gridItemWidth)
                .height(80)
                .textAlign(TextAlign.Center)
            }
          }
        }, (day: string) => day)
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .columnsGap(this.columnGap)
      .rowsGap(10)
      .scrollBar(BarState.Off)
      .width('100%')
      .backgroundColor(0xFAEEE0)
      .height(350)
    }
  }
}

B.通过GridLayoutOptions

@Entry
@Component
struct GridExample3 {
  numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8','9']
  scroller: Scroller = new Scroller()
  layoutOptions1: GridLayoutOptions = {
    regularSize: [1, 1],
    irregularIndexes: [0, 5],
  }

  build() {
    Column({ space: 5 }) {
      Grid(this.scroller, this.layoutOptions1) {
          ForEach(this.numbers, (day: string) => {
            GridItem() {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width('100%')
                .height(80)
                .textAlign(TextAlign.Center)
            }
          }, (day: string) => day)
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .scrollBar(BarState.Off)
      .width('100%')
      .backgroundColor(0xFAEEE0)
      .height(350)
    }.align(Alignment.Center)
  }
}

C.通过设置GridItem的columnStart和columnEnd

// xxx.ets
@Entry
@Component
struct GridExample3 {
  numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  scroller: Scroller = new Scroller()

  build() {
    Column({ space: 5 }) {
      Grid(this.scroller) {
        ForEach(this.numbers, (day: string) => {
          if (day === '0' || day === '5') {
            GridItem() {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width('100%')
                .height(80)
                .textAlign(TextAlign.Center)
            }.columnStart(1).columnEnd(4)
          } else {
            GridItem() {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width('100%')
                .height(80)
                .textAlign(TextAlign.Center)
            }
          }
        }, (day: string) => day)
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .scrollBar(BarState.Off)
      .width('100%')
      .backgroundColor(0xFAEEE0)
      .height(350)
    }
  }
}

解析:

A选项可以实现下图Grid布局。通过设置不同GridItem的宽度,当day为’0’或’5’时,将对应的GridItem宽度设置为其他GridItem宽度的4倍加上3倍的列间距,从而实现了特定的布局效果。

B选项使用GridLayoutOptions,但根据提供的代码,regularSize和irregularIndexes的设置似乎不太符合要求的布局。

C选项通过设置GridItem的columnStart和columnEnd,但是代码中没有明确指定不同GridItem的columnStart和columnEnd的值,无法确定是否能实现所需布局。

因此,答案是A。

10.从桌面冷启动如下应用,点击Change按钮5次,整个过程中,代码中的2条log依次出现的次数,最初和最后画面上显示的【num = ?】的数字是

// PageOne.ets
@Component
export struct PageOneTmp {
  @Consume('pageInfos') pageInfos: NavPathStack;

  build() {
    NavDestination() {
      Column() {
        Button('toPageTwo', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPathByName('pageTwo',"")
          })
        Button('get', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            console.log('获取全部名为name的NavDestination页面的位置索引', JSON.stringify(this.pageInfos.getIndexByName('pageOne')))
          })
      }.width('100%').height('100%')
    }.title('pageOne')
    .onBackPressed(() => {
      const popDestinationInfo = this.pageInfos.pop()
      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
      return true
    })
  }
}

// PageTwo.ets
export class Pages {
  names: string = ""
  values: NavPathStack | null = null
}

@Builder
export function pageTwoTmp(info: Pages) {
  NavDestination() {
    Column() {
      Button('toPageOne', { stateEffect: true, type: ButtonType.Capsule })
        .width('80%')
        .height(40)
        .margin(20)
        .onClick(() => {
          (info.values as NavPathStack).pushPathByName('pageOne', null)
        })
    }.width('100%').height('100%')
  }.title('pageTwo')
  .onBackPressed(() => {
    (info.values as NavPathStack).pop()
    return true
  })
}

A、0,6,1,6
B、1,5,1,6
C、2,4,1,6
D、2,4,1,2

解析:题目代码出错,不确定答案是哪一个。

11.根据上面代码,以下解释正确的是

enum Mode {
  fullScreen,
  halfScreen
}

@Entry
@Component
struct Page {
  @State title: string  = "";
  @State mode: Mode = Mode.fullScreen;

  isShownTitle(): boolean {
    if (this.mode == Mode.fullScreen) {
      this.title = "Title";

      return true;
    } else {
      this.title= "Section";
      return false;
    }
  }

  build() {
    Column() {
      if (this.isShownTitle()) {
        Text(`${this.title}`)
      } else {
        Text(`${this.title}`)
      }
      ChangeMode({ mode: this.mode})

    }
  }
}

@Component
struct ChangeMode {
  @Prop mode: Mode;
  build() {
    Row({space: 20}) {
      Button('full screen').onClick(() => {
        this.mode = Mode.fullScreen;
      })
      Button('half screen').onClick(() => {
        this.mode = Mode.halfScreen;
      })
    }
  }
}

A.为了避免@Prop的拷贝,可以优化使用@Link,在该例子中行为和@Prop一样。
B.在自定义组件Pagebuild方法里改变状态变量是非法操作,可能导致未定义的异常UI行为。
C.本例子可以运行起来,所以代码没有问题。
D.在ChangeMode里改变mode的值,会触发其父组件PageTitle内容的切换

解析:D。在ChangeMode组件中改变mode的值,会通过@Prop传递给Page组件,从而触发Page组件中isShownTitle()方法的重新执行,导致Title内容的切换。

A选项中,@Prop和@Link在这种情况下的行为是不同的,@Prop用于父子组件之间的单向数据传递,而@Link用于双向数据绑定。

B选项,在Page的build方法中改变状态变量本身不一定是非法操作,具体取决于代码的逻辑和上下文。

C选项,虽然例子可能可以运行,但代码中可能存在一些潜在的问题或不太规范的地方,例如使用@Prop的方式可能不是最优的,以及代码的可读性和可维护性等方面。

12.如果想让**outer button响应事件,hitTestBehavior**该怎么配

mport promptAction from '@ohos.promptAction';
// xxx.ets
@Entry
@Component
struct HitTestBehaviorExample {
  build() {
    // outer stack
    Stack() {
      Button('outer button')
        .onClick((event) => {
          promptAction.showToast({ message: `click事件触发------++++2` });
        })
      // inner stack
      Stack() {
        Button('inner button')
          .onTouch((event) => {
            promptAction.showToast({ message: `click事件触发------1` });
          })
      }
      .width("100%").height("100%")
      .hitTestBehavior()
      .onTouch((event) => {
        console.info('stack touched type: ' + (event as TouchEvent).type)
      })

    }.width(300).height(300)
  }
}

A.HitTestMode.Default
B.HitTestMode.None
C.HitTestMode.Transparent
D.HitTestMode.Block

解析:C。当希望outer button响应事件,而inner stack不拦截事件时,应将hitTestBehavior配置为HitTestMode.Transparent。这样,inner stack会将触摸事件透传给outer button,使其能够响应事件。

A选项HitTestMode.Default通常是默认行为,可能会导致inner stack拦截事件。

B选项HitTestMode.None会使组件完全不参与命中测试,即不会响应任何事件。

D选项HitTestMode.Block会使组件拦截所有事件,导致outer button无法响应事件。

13.已知下列代码PageOne页面为navigation中的某一子页面,依次点击PageOne页面中toPageTwo按钮,PageTwo页面中toPageOne按钮,此时点击get按钮获取全部名为name的NavDestination页面的位置索引为

// PageOne.ets
@Component
export struct PageOneTmp {
  @Consume('pageInfos') pageInfos: NavPathStack;

  build() {
    NavDestination() {
      Column() {
        Button('toPageTwo', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPathByName('pageTwo',"")
          })
        Button('get', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            console.log('获取全部名为name的NavDestination页面的位置索引', JSON.stringify(this.pageInfos.getIndexByName('pageOne')))
          })
      }.width('100%').height('100%')
    }.title('pageOne')
    .onBackPressed(() => {
      const popDestinationInfo = this.pageInfos.pop()
      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
      return true
    })
  }
}

// PageTwo.ets
export class Pages {
  names: string = ""
  values: NavPathStack | null = null
}

@Builder
export function pageTwoTmp(info: Pages) {
  NavDestination() {
    Column() {
      Button('toPageOne', { stateEffect: true, type: ButtonType.Capsule })
        .width('80%')
        .height(40)
        .margin(20)
        .onClick(() => {
          (info.values as NavPathStack).pushPathByName('pageOne', null)
        })
    }.width('100%').height('100%')
  }.title('pageTwo')
  .onBackPressed(() => {
    (info.values as NavPathStack).pop()
    return true
  })
}

A.[0,2]
B.[1,2]
C.[0,1]
D.[2,1]

解析:C。依次点击PageOne页面中toPageTwo按钮,此时页面栈中会添加PageTwo页面的路径。然后在PageTwo页面中点击toPageOne按钮,页面栈中会再次添加PageOne页面的路径。

此时点击get按钮获取全部名为name的NavDestination页面的位置索引(但代码中实际获取的是名为“pageOne”的页面索引),由于页面栈中此时有两个PageOne页面的路径,根据栈的先进后出原则,第一个PageOne页面的索引为0,第二个PageOne页面的索引为1。

所以获取到的位置索引为[0, 1],答案选C。

14.开发者小张正在使用DevEco Studio开发一款HarmonyOS应用,他遇到了一个仅在应用实际运行环境中出现的问题,需要调试已部署在设备上的应用以定位问题根源,为了能够在应用已经运行的情况下介入调试,小张应该采用哪种调试方法
A.使用Debug功能,将应用重新推包运行调试
B.使用“Profile”功能,因为这同样能提供对运行时应用的监控与调试能力。
C.Attach Debugger to Process,这允许他连接到正在运行的应用进程进行调试。
D.Run without Debugging,先让应用自由运行,随后手动附加调试

解析:C。开发者小张遇到了仅在应用实际运行环境中出现的问题,需要调试已部署在设备上的应用以定位问题根源,在这种情况下,使用Attach Debugger to Process的调试方法可以允许他连接到正在运行的应用进程进行调试,从而能够在应用已经运行的情况下介入调试。

A选项,使用Debug功能将应用重新推包运行调试,可能无法复现仅在实际运行环境中出现的问题。

B选项,使用“Profile”功能主要用于性能分析和监控,对于调试特定问题的帮助可能有限。

D选项,Run without Debugging先让应用自由运行,随后手动附加调试器,这种方式可能不太方便,而且也不一定能满足调试的需求。

因此,小张应该采用C选项的调试方法。

15.项目需要为不同的设备形态(如手机、智能手表)提供定制化构建。请说明如何在DevEco Studio中设置不同的构建配置,以生成针对不同设备的hap包?
A.在工程级别build-profile.json5定义多个product,在每个product的config/distributionFilter中定义不同的设备类型
B.在模块级别build-profile.json5定义多个target,在每个target的config/distributionFilter中定义不同的设备类型
C.在模块级别build-profile.json5定义多个target,在每个target的config/deviceType中定义不同的设备类型
D.在工程级别build-profile.json5定义多个product,在每个product的config/deviceType中定义不同的设备类型

解析:D。在DevEco Studio中,为了为不同的设备形态提供定制化构建并生成针对不同设备的hap包,可以在工程级别build - profile.json5定义多个product,在每个product的config/deviceType中定义不同的设备类型。

A选项中,在config/distributionFilter中定义设备类型的方式不太准确,通常是在config/deviceType中进行定义。

B和C选项中,在模块级别进行定义不太符合常规的做法,一般是在工程级别进行相关的配置。

因此,正确答案是D。

16.小李正在使用DevEco Studio进行HarmonyOS应用的开发工作,他需要对一个频繁被调用的函数calculateData()进行重构,为了帮助小李高效地找到calculateData()函数的所有引用位置,并确保重构时考虑周全,以下哪个步骤是正确的使用DevEco Studio的“Find Usages”功能的操作方法
A.小李只需将光标定位在calculateData()函数名上,右键点击并选择“Find Usages”,或者直接使用快捷键Alt + F7(macOS为Option + F7),DevEco Studio会自动列出该函数在项目中的所有引用位置。
B.小李应将光标置于calculateData()函数的名称上,按下Ctrl + Shift + F(macOS为Command + Shift + F)全局搜索该函数名,然后在搜索结果中筛选出真正的调用位置。
C.小李应当在项目目录树中找到calculateData()函数所在的文件,直接双击打开文件,然后逐行扫描代码以手动查找该函数的所有调用位置。
D.小李应该在菜单栏中选择“Navigate” > “Class”来打开类浏览器,从中找到calculateData()函数,并在此界面中手动检查所有引用。

解析:A。小李只需将光标定位在calculateData()函数名上,右键点击并选择“Find Usages”,或者直接使用快捷键Alt + F7(macOS为Option + F7),DevEco Studio会自动列出该函数在项目中的所有引用位置,这是正确使用“Find Usages”功能的操作方法。

B选项中,Ctrl + Shift + F(macOS为Command + Shift + F)是全局搜索的快捷键,但不一定能直接筛选出真正的调用位置。

C选项中,逐行扫描代码手动查找所有调用位置效率较低,不是最佳方法。

D选项中,在菜单栏中选择“Navigate” > “Class”来打开类浏览器并手动检查所有引用,也不是最高效的方式。

因此,正确答案是A。

17.一个复杂的项目,该项目不仅包含主入口模块(Entry Module),还有多个特性的功能模块(Feature Modules/HSP),并且这些模块间存在着相互调用关系。为了确保在调试过程中能够完整地测试所有交互逻辑,需要将涉及到的所有模块的HAP包都部署到目标设备上。请从以下选项中选择正确的操作步骤来配置DevEco Studio,以便一次性部署和调试项目中的多个模块
A.在项目结构界面手动选择每个模块,单独编译并逐一将生成的HAP包通过HDC命令推送到设备上。
B.无需特殊配置,DevEco Studio会自动检测到项目中的所有模块依赖,并在每次调试运行时自动部署所有相关HAP包。
C.直接点击运行按钮,DevEco Studio会弹出对话框询问需要部署哪些模块,从中选择需要的模块后开始调试。
D.进入“Run > Edit Configurations”菜单,在“Deploy Multi Hap”选项卡下,勾选“Deploy Multi Hap Packages”,随后在列表中选择需要部署的模块。

解析:B。对于一个复杂的项目,包含主入口模块(Entry Module)和多个特性的功能模块(Feature Modules/HSP),且这些模块间存在相互调用关系,为了确保在调试过程中能完整测试所有交互逻辑,将涉及的所有模块的HAP包部署到目标设备上,DevEco Studio通常会自动检测到项目中的所有模块依赖,并在每次调试运行时自动部署所有相关HAP包,无需特殊配置。

A选项中手动选择每个模块、单独编译并推送的方式过于繁琐,不符合高效开发的要求。

C选项中直接点击运行按钮并弹出对话框选择模块的方式,可能会增加操作步骤,而且不一定能确保自动部署所有相关HAP包。

D选项中进入特定菜单进行勾选和选择模块的操作相对复杂,不是最便捷的方式。

因此,正确答案是B。

18.当前您在开发一个ArkTS、Stage模型的HarmonyOS工程,关于当前ArkTS工程目录结构,下列选项说法错误的是?
A.oh-package.json5:描述依赖配置,如:依赖覆盖(overrides)、依赖关系重写(overrideDependencyMap)和参数化配置(parameterFile)等。
B.AppScope > app.json5:应用的全局配置信息。
C.entry > src > main > module.json5:Stage模型模块配置文件,主要包含HAP的配置信息、应用在具体设备上的配置信息以及应用的全局配置信息。
D.build-profile.json5:应用级编译构建任务脚本。

解析:C。entry > src > main > module.json5是Stage模型模块配置文件,主要包含HAP的配置信息以及应用在具体设备上的配置信息,但不包含应用的全局配置信息,应用的全局配置信息在AppScope > app.json5中。

A选项,oh - package.json5确实用于描述依赖配置。

B选项,AppScope > app.json5用于存储应用的全局配置信息。

D选项,build - profile.json5是应用级编译构建任务脚本。

综上所述,说法错误的是C选项。

19.在开发HarmonyOS应用工程时,随着业务的发展,现在需要创建一个模块,关于在DevEco Studio中创建Module,下列选项哪种方式是错误的?
A.鼠标移到工程目录顶部,单击鼠标右键,选择New > Module…,开始创建新的Module,此时该module将创建在工程根目录下。
B.选中工程目录中任意文件,然后在菜单栏选择File > New > Module…,开始创建新的Module,此时该module将创建在工程根目录下。
C.在工程根目录下创建一个新的Directory,可在该目录下单击鼠标右键,选择New > Module…,创建新的Module,此时module将创建在该文件目录下。
D.在hvigor目录下,单击鼠标右键,选择New > Module…,创建新的Module,此时module将创建在该文件目录下。

解析:D。在hvigor目录下,单击鼠标右键,选择New > Module…创建新的Module的方式是错误的。通常,在DevEco Studio中创建Module的正确方式是:
A. 鼠标移到工程目录顶部,单击鼠标右键,选择New > Module…,开始创建新的Module,此时该module将创建在工程根目录下。
B. 选中工程目录中任意文件,然后在菜单栏选择File > New > Module…,开始创建新的Module,此时该module将创建在工程根目录下。
C. 在工程根目录下创建一个新的Directory,可在该目录下单击鼠标右键,选择New > Module…,创建新的Module,此时module将创建在该文件目录下。

而在hvigor目录下进行相关操作并不是创建Module的常规方式。

20.开发者小李遇到了一个复杂的问题,该问题仅在特定的代码执行路径上出现,且难以复现。他使用的是C++进行核心算法开发,代码的逻辑密集且对性能要求极高,DevEco Studio为C/C++开发者提供的高级调试能力,以下哪个能力可以帮助小李查看代码历史执行路径,回溯到关键的变量状态
A.代码静态分析:提供静态代码检查工具,通过语法和逻辑分析帮助预防潜在错误,但不涉及运行时问题定位
B.传统调试模式:仅允许在当前断点暂停代码执行,查看调用堆栈和当前变量信息,但无法追溯历史执行状态
C.反向调试能力:允许开发者在调试过程中回退回到之前的代码行或断点,不仅查看过去的堆栈信息,还能重现历史的全局、静态和局部变量状态,帮助深入理解代码历史行为,特别是对于复杂逻辑和难以复现的bug定位至关重要
D.实时代码修改与运行时效果查看:支持在调试过程中修改代码并立即查看修改效果,适用于快速迭代,但不聚焦于问题追溯

解析:C。在开发者小李遇到的问题中,由于问题仅在特定的代码执行路径上出现且难以复现,需要一种能够查看代码历史执行路径、回溯关键变量状态的调试能力。

A选项的代码静态分析主要用于预防潜在错误,无法解决当前的问题。

B选项的传统调试模式无法追溯历史执行状态,不符合需求。

D选项的实时代码修改与运行时效果查看主要用于快速迭代,对于追溯历史执行路径和变量状态帮助不大。

而C选项的反向调试能力允许开发者回退到之前的代码行或断点,查看过去的堆栈信息并重现历史的变量状态,对于解决小李的问题至关重要。

21.开发者小林正在使用DevEco Studio开发一款HarmonyOS应用,并在真机上进行调试。他在运行应用的过程中突然发现一处UI布局需要微调,希望在不中断当前应用运行的情况下看到调整效果,基于DevEco Studio提供的Hot Reload(热重载)能力,以下哪一种做法能让小林最有效地实现他的需求、
A.使用模拟器替代真机进行调试,因为Hot Reload仅在模拟器上支持代码改动的即时生效
B.继续运行应用,手动重启应用后检查布局是否符合预期
C.立即停止应用,修改代码后重新编译并部署到真机上
D.在不关闭应用的情况下,直接修改代码并保存,借助Hot Reload功能在真机上实时查看布局调整的效果

解析:D。

DevEco Studio 提供的 Hot Reload(热重载)能力可以在不中断当前应用运行的情况下,实时看到代码修改后的效果。

A 选项中,使用模拟器替代真机进行调试虽然模拟器可能支持 Hot Reload 但真机调试更能反映实际设备上的情况,且不是最直接满足在真机上调试且不中断的需求,所以该选项不是最有效的做法;

B 选项手动重启应用后检查布局不符合不中断应用运行且实时查看调整效果的要求;

C 选项立即停止应用,修改代码后重新编译并部署到真机上,这个过程会中断应用,也不符合不中断的要求;

而 D 选项在不关闭应用的情况下,直接修改代码并保存,借助 Hot Reload 功能在真机上实时查看布局调整的效果,这正是小林所需要的最有效实现需求的做法,利用 Hot Reload 可以快速在真机上看到 UI 布局的实时变化,方便进行微调,大大提高开发效率。

综上所述,正确答案是 D。同时,确保在 DevEco Studio 中正确配置和启用了 Hot Reload 功能以保证其正常工作。

22.应用开发中使用的各类资源文件,需要放入特定子目录中存储管理,以下关于资源说法错误的是
A.stage模型多工程情况下,共有的资源文件放到AppScope下的resources目录。
B.base目录是默认存在的目录,二级子目录element用于存放字符串、颜色、布尔值等基础元素,media、profile存放媒体、动画、布局等资源文件。
C.rawfile目录,支持创建多层子目录,子目录名称可以自定义,文件夹内可以自由放置各类资源文件。目录中的资源文件会被编译成二进制文件,并赋予资源文件ID。
D.resfile目录,应用安装后,resfile资源会被解压到应用沙箱路径,通过Context属性resourceDir获取到resfile资源目录后,可通过文件路径访问。

解析:

D 选项说法错误。

在 HarmonyOS 应用开发中:
A 选项,stage 模型多工程情况下,共有的资源文件放到 AppScope 下的 resources 目录,此说法正确。
B 选项,base 目录默认存在,二级子目录 element 用于存放字符串、颜色、布尔值等基础元素,media、profile 存放媒体、动画、布局等资源文件,该说法正确。
C 选项,rawfile 目录支持创建多层子目录,子目录名称可自定义,文件夹内可自由放置各类资源文件,且目录中的资源文件会被编译成二进制文件,并赋予资源文件 ID,这种表述是准确的。

而 D 选项中应为“res 资源会被编译到 hap 包中,应用安装后,res 资源会被解压到应用沙箱路径,通过 Context 属性 resourceDir 获取到 res 资源目录后,可通过文件路径访问”,而不是 resfile 目录。

23.HAR(Harmony Archive)是HarmonyOS提供的共享包,以下关于HAR的描述错误的是
A.HAR不支持引用AppScope目录中的资源。在编译构建时,AppScope中的内容不会打包到HAR中,因此会导致HAR资源引用失败。
B.HAR不支持在设备上单独安装/运行,只能作为应用模块的依赖项被引用。
C.HAR不支持使用page页面。
D.HAR可以作为二方库和三方库提供给其他应用使用,如果需要对代码资产进行保护时,建议开启混淆能力。

解析:C 选项的描述错误。

HAR 支持使用 page 页面。

A 选项,HAR 确实不支持引用 AppScope 目录中的资源,编译构建时 AppScope 中的内容不会打包到 HAR 中,可能导致资源引用失败。
B 选项,HAR 不能在设备上单独安装/运行,只能作为应用模块的依赖项被引用,这种说法是正确的。
D 选项,HAR 可以作为二方库和三方库给其他应用使用,需要保护代码资产时建议开启混淆能力,表述无误。

综上所述,选择 C 选项。

24.want参数的entities匹配规则错误的是
A.调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities为空,则entities匹配失败。
B.调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities不为空且包含调用方传入的want参数的entities,则entities匹配成功。
C.调用方传入的want参数的entities为空,待匹配应用组件的skills配置中的entities为空,则entities匹配成功。
D.调用方传入的want参数的entities为空,待匹配应用组件的skills配置中的entities不为空,则entities匹配失败。

解析:以下是对每个选项的分析:

A 选项:调用方传入的 want 参数的 entities 不为空,而待匹配应用组件的 skills 配置中的 entities 为空,这种情况下 entities 匹配失败,该描述是正确的。

B 选项:调用方传入的 want 参数的 entities 不为空,待匹配应用组件的 skills 配置中的 entities 不为空且包含调用方传入的 want 参数的 entities 时,entities 匹配成功,此描述正确。

C 选项:调用方传入的 want 参数的 entities 为空,待匹配应用组件的 skills 配置中的 entities 为空,此时 entities 匹配成功,该表述正确。

D 选项:调用方传入的 want 参数的 entities 为空,待匹配应用组件的 skills 配置中的 entities 不为空,这种情况应该是匹配成功,而不是匹配失败。所以该选项的描述错误。

综上所述,选择 D 选项。

25.在编译构建HAP时,会从HAP模块及依赖的模块中收集资源文件,如果不同模块下的资源文件出现重名冲突时,会按照优先级进行覆盖,现在有一个HAP依赖了两个HAR,依赖配置如下所示:

// oh-package.json5
{
  "dependencies": {
    "dayjs": "^1.10.4",
    "lottie": "^2.0.0"
  }
}

26.在资源覆盖时,以下优先级排序正确的是()
A.AppScope>HAP包自身模块>lottie模块>dayjs模块
B.HAP包自身模块>lottie模块>dayjs模块>AppScope
C.HAP包自身模块>dayjs模块>lottie模块>AppScope
D.AppScope>HAP包自身模块>dayjs模块>lottie模块

解析:C选项正确。

在编译构建 HAP 时,资源覆盖的优先级排序通常是:AppScope > HAP 包自身模块 > 依赖的模块。

所以应该是 AppScope > HAP 包自身模块 > dayjs 模块>lottie 模块 。

综上所述,选择 A 选项。

27.可以通过下面那个接口拉起导航类的垂域面板
A.startAbility
B.startAbilityForResult
C.startAbilityByType
D.startAbilityByCall

解析:通过startAbilityByType拉起垂类应用,所以答案选C。

28.一个应用有2个UIAbility组件,其module.json中abilities标签的配置如下方代码。
在手机设备上,执行如下操作后:
1.启动UIAbility1,然后back键返回销毁UIAbility1;
2.启动UIAbility2, 然后back键返回销毁UIAbility2;
3.启动UIAbility2, 然后back键返回销毁UIAbility2;
进入多任务列表,能看看到该应用的几个任务视图:

"abilities": [
  {
    "name": "UIAbility1",
    "srcEntry": "./ets/entryability/Ability1.ets",
    "description": "$string:EntryAbility_desc",
    "icon": "$media:icon",
    "label": "$string:Ability1_label",
    "startWindowIcon": "$media:icon",
    "startWindowBackground": "$color:start_window_background",
    "exported": true,
    "launchType": multiton
  },
  {
    "name": "UIAbility2",
    "srcEntry": "./ets/entryability/Ability2.ets",
    "description": "$string:Ability2_desc",
    "icon": "$media:icon",
    "label": "$string:Ability2_label",
    "startWindowIcon": "$media:icon",
    "startWindowBackground": "$color:start_window_background",
    "exported": true,
    "launchType": singleton,
    "removeMissionAfterTerminate":true
  }
]

A、0个
B、1个
C、2个
D、3个

解析:在上述操作后,进入多任务列表能看到该应用的 1 个任务视图。所以答案选B。

UIAbility1 的 launchType 为 multiton,每次启动都会创建新的实例,销毁后不会在多任务列表中留下记录。

UIAbility2 的 launchType 为 singleton,且设置了 removeMissionAfterTerminate 为 true,意味着在销毁后会从多任务列表中移除。

所以在完成上述操作后,多任务列表中只会有当前正在运行的 UIAbility2 的任务视图,如果此时 UIAbility2 也被销毁了,那么多任务列表中就没有该应用的任务视图了。

29.开发者开发了一个应用,该应用只有一个hap包,其module.json5中abilities的配置如下
所示,包含1个UIAbility(无Web组件)、1个FormExtensionAbility组件、
1个WorkSchedulerExtensionAbility组件,那么该应用在运行过程中,
最多会存在几个应用进程:

"abilities": [

  {

    "name" : "EntryAbility",

    "srcEntry" : "./etc/entryability/EntryAbility.ts",

    "description" : "$string:EntryAbility_desc",

    "exported" : ture

  }

],

"extensionAbilities": [

  {

    "name": "ClockFormExtensionAbility",

    "srcEntrance": "./ets/form/ClockFormExtensionAbility.ts",

    "type": "form"

  },

  {

    "name": "TipWorkSchedulerExtensionAbility",

    "srcEntrance": "./ets/service/TipWorkSchedulerExtensionAbility.ts",

    "type": "workScheduler"

  }

]

A.4个
B.1个
C.2个
D.3个

解析:B。

一个应用中,UIAbility 是应用的主要界面能力,FormExtensionAbility 组件和 WorkSchedulerExtensionAbility 组件是扩展能力。

在这种情况下,通常只有一个应用进程来管理整个应用的运行,包括 UIAbility 和各种扩展能力。

所以该应用在运行过程中最多会存在 1 个应用进程,选择 B 选项。

30.1.在UIAbility的onCreate生命周期中通过EventHub的on注册"event1"和"event2"事件。

import { hilog } from '@kit.PerformanceAnalysisKit';

import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit';

const DOMAIN_NUMBER: number = 0xFF00;

const TAG: string = '[EventAbility]';

export default class EntryAbility extends UIAbility {

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

// 获取UIAbility实例的上下文

let context = this.context;

// 获取eventHub

let eventhub = this.context.eventHub;

// 执行订阅操作

eventhub.on('event1', this.eventFunc);

eventhub.on('event2', this.eventFunc);

hilog.info(DOMAIN_NUMBER, TAG, '%{public}s', 'Ability onCreate');

}

// ...

eventFunc(argOne: Context, argTwo: Context): void {

hilog.info(DOMAIN_NUMBER, TAG, 'receive. ' + `${argOne}, ${argTwo}`);

return;

}

}

2.在UI组件的click处理事件中调用如下的eventHubFunc,连续点击2次该控件后,运行日志输出是什么:

import common from '@kit.AbilityKit';;

import { promptAction } from '@kit.ArkUI';

@Entry

@Component

struct Page_EventHub {

private context = getContext(this) as common.UIAbilityContext;

eventHubFunc() : void {

this.context.eventHub.emit('event1');

this.context.eventHub.emit('event2', 2, 'test2');

this.context.eventHub.off('event1');

}

build() {

Column() {

// ...

List({ initialIndex: 0 }) {

ListItem() {

Row() {

// ...

}

.onClick(() => {

this.eventHubFunc();

promptAction.showToast({

message: $r('app.string.EventHubFuncA')

});

})

}

}

// ...

}

// ...

}

}

A.
[Example].[Entry].[EntryAbility] receive. []
[Example].[Entry].[EntryAbility] receive. [2,“test2”]
[Example].[Entry].[EntryAbility] receive. []
[Example].[Entry].[EntryAbility] receive. [2,“test2”]

B.
[Example].[Entry].[EntryAbility] receive. []
[Example].[Entry].[EntryAbility] receive. [2,“test2”]

C.
[Example].[Entry].[EntryAbility] receive. []
[Example].[Entry].[EntryAbility] receive. [2,“test2”]
[Example].[Entry].[EntryAbility] receive. [2,“test2”]

D.
[Example].[Entry].[EntryAbility] receive. []
[Example].[Entry].[EntryAbility] receive. [2,“test2”]
[Example].[Entry].[EntryAbility] receive. []

解析:

A。

在第一次点击控件时:

  • this.context.eventHub.emit('event1'); 触发 event1 事件,EntryAbility 中的 eventFunc 被调用,输出 [Example].[Entry].[EntryAbility] receive. []
  • this.context.eventHub.emit('event2', 2, 'test2'); 触发 event2 事件,EntryAbility 中的 eventFunc 被调用,输出 [Example].[Entry].[EntryAbility] receive. [2,"test2"]

在第二次点击控件时,重复上述过程,再次输出:

  • [Example].[Entry].[EntryAbility] receive. []
  • [Example].[Entry].[EntryAbility] receive. [2,"test2"]

综上所述,选择 A 选项。

31.hiAppEvent提供的Watcher接口,()属性不配置,会导致编译报错,产生"ArkTS Compiler Error".
A.name
B.onReceive
C.triggerCondition
D.onTrigger

解析:A。

在 hiAppEvent 提供的 Watcher 接口中,name 属性不配置会导致编译报错,产生 “ArkTS Compiler Error” 。

onReceive 用于定义接收到事件时的处理逻辑,triggerCondition 用于设置触发条件,onTrigger 可能并非 Watcher 接口的标准属性。

综上所述,选择 A 选项。

32.作为一个应用开发者,想搭建运维平台,想在应用内定时读取当前的内存信息,可以通过()接口来实现。
A.hiChecker
B.hiLog
C.hiAppEvent
D.hiDebug

解析:作为一个应用开发者,想搭建运维平台,想在应用内定时读取当前的内存信息,可以通过hiDebug接口来实现。

hiDebug提供了一些调试和性能分析相关的功能,可能包括获取内存使用情况等信息,这对于运维平台监控应用的内存状态等是有帮助的。

hiChecker主要用于进行一些检查和校验工作;hiLog主要用于日志输出;hiAppEvent主要用于处理事件相关的操作,它们虽然在应用开发中都有各自的用途,但在定时读取内存信息方面,通常不是最直接相关的接口。

综上所述,答案选D

33.我们需要避免在逐帧调用的接口中执行耗时操作,下面哪个选项不属于上述的接口?
A.onAreaChange
B.onScroll
C.aboutToReuse
D.onTouch

解析:C 选项“aboutToReuse”不属于逐帧调用的接口。

A 选项“onAreaChange”、B 选项“onScroll”和 D 选项“onTouch”通常会在与用户交互或界面变化的过程中频繁触发,属于逐帧调用的接口,在这些接口中执行耗时操作可能会导致性能问题。

综上所述,选择 C 选项。

34.当标记了@Reuseable的自定义组件实现了组件复用后,这个组件的复用范围是什么?
A.标记了@Reuseable的自定义组件的父组件范围内
B.整个应用内都可以复用
C.整个页面都可以复用
D.标记了@Reuseable的自定义组件的外层容器节点范围内

解析:A。当标记了 @Reuseable 的自定义组件实现了组件复用后,这个组件通常在标记了 @Reuseable 的自定义组件的父组件范围内复用。

B 选项整个应用内都可以复用过于宽泛,一般不会是整个应用。

C 选项整个页面都可以复用也不太准确,不一定是整个页面。

D 选项标记了 @Reuseable 的自定义组件的外层容器节点范围内不太准确,通常是父组件范围内。

综上所述,选择 A 选项。

35.为了提高性能,所以List组件支持懒加载,可以通过配置cachedCount属性设置缓存列表项的数量。当我们不设置List的属性cachedCount时,该属性的默认值是?
A.1
B.2
C.0
D.3

解析:D。当不设置 List 的属性 cachedCount 时,该属性的默认值是 3 。

综上所述,选择 D 选项。

36.下面持续集成描述哪项是错误的:
A.持续集成在大型项目(有几十个项目组)也能应用,即便是项目组开发进度不统一也没问题
B.持续集成就是持续编译,二者异曲同工
C.Martin Fowler说过,”持续集成并不能消除Bug,而是让它们非常容易发现和改正。”
D.持续集成(CI, Continuous Intergation): 指频繁的,一天多次将代码集成到主干。

解析:B 选项的描述是错误的。

持续集成不仅仅是持续编译,它还包括自动构建、自动测试、代码质量检查等一系列的流程和活动,旨在尽早发现和解决集成中的问题,提高软件质量和开发效率。

A 选项,持续集成在大型项目中,即便项目组开发进度不统一也能应用,这种说法是合理的,通过合理的配置和管理可以实现。

C 选项,Martin Fowler 的这句话准确地指出了持续集成的作用之一。

D 选项,对持续集成的定义是较为准确的。

综上所述,选择 B 选项。

37.一个应用项目工程中,模块依赖关系如下图所示,那么在最终编译结果.app文件中,存在的编译产物是:

HarmonyOS应用开发者高级认证题目(7月新版,答案&解析,持续更新)-LMLPHP

A.A.hap + B.har + D.hsp
B.A.hap + D.hsp + C.har
C.A.hap + B.har + C.har + D.hsp
D.A.hap + D.hsp

答案:D

38.以下关于应用架构技术选型说法不正确的是()
A.一些应用的扩展能力,比如备份、服务卡片,可以采用ExtensionAbility做成单独的feature HAP包,独立分发。
B.元服务和应用可以共用一个代码工程,采用多目标产物构建方式,构建出应用和元服务两个产物,用于上架。
C.对于初始版本的应用,功能比较简单,可以考虑采用单HAP加上多个HAR工程构建代码工程。
D.随着业务的发展,应用功能会越来越多,某些功能可以做成动态加载,动态加载的模块采用HAR工程来构建,方便复用和共享。

解析:以下是对每个选项的分析:

A 选项:一些应用的扩展能力采用 ExtensionAbility 做成单独的 feature HAP 包独立分发是一种常见的技术选型,该说法正确。

B 选项:元服务和应用可以共用一个代码工程,通过多目标产物构建方式分别生成应用和元服务的产物用于上架,这种做法是可行的,该说法正确。

C 选项:对于初始版本功能简单的应用,通常不采用单 HAP 加上多个 HAR 工程构建代码工程,这种方式相对复杂,对于简单应用不太必要。所以该说法不正确。

D 选项:随着业务发展,将某些功能做成动态加载模块,并采用 HAR 工程构建以方便复用和共享,是合理的技术选型,该说法正确。

综上所述,不正确的是 C 选项。

39.某业务团队的架构师发现某个特性用的频率比较少,但是这个特性占用空间资源还是比较大的。为了减少首包下载体积,准备将该特性解耦出来,并对外提供API方便主模块调用。以下说法正确的是()
A.将该特性做成按需加载的hsp包,暴露接口给主模块使用。
B.将该特性做成H5模块,通过web组件加载远程资源使用。
C.将该特性做成hap包,通过Ability组件暴露出来给主app使用。
D.将该特性做成动态加载的har包,暴露接口给主模块使用。

解析:D 选项的说法正确。

将该特性做成动态加载的 HAR 包,并暴露接口给主模块使用,这样可以在需要的时候进行加载,从而减少首包下载体积。

A 选项,做成按需加载的 hsp 包的说法不太常见,通常不是这种处理方式。

B 选项,将特性做成 H5 模块通过 web 组件加载远程资源使用,可能会存在网络延迟等问题,不一定能很好地满足减少首包体积的需求。

C 选项,做成 HAP 包不太适合,因为 HAP 包通常是应用的主要模块,不太便于实现动态加载和减少首包体积。

综上所述,选择 D 选项。

40.以下关于动态import说法正确的是()
A.动态import不支持导入SDK的API,如@ohos.*
B.动态import和静态import相比,灵活性更好,性能更好。
C.动态import支持加载HSP模块、HAR模块、OHPM包、Native库
D.动态import支持懒加载,所以不能用于提升页面的加载速度。

解析:以下是对每个选项的分析:

A 选项:动态 import 支持导入 SDKAPI,如 @ohos.*,所以该选项错误。

B 选项:动态 import 灵活性更好,但性能通常不如静态 import,因为动态 import 涉及到在运行时进行模块的加载,会增加一些开销,所以该选项错误。

C 选项:动态 import 支持加载 HSP 模块、HAR 模块、OHPM 包、Native 库,该选项正确。

D 选项:动态 import 支持懒加载,通过按需加载模块可以减少初始页面的加载负担,从而在一定程度上提升页面的加载速度,而不是不能用于提升页面加载速度,所以该选项错误。

综上所述,正确的是 C 选项。

41.WebSocket连接开发步骤描述错误的是
A.调用Session.start方法开启metadata数据输出
B.创建一个WebSocket连接,返回一个WebSocket对象
C.导入需要的webSocket模块
D.(可选)订阅WebSocket的打开、消息接收、关闭、Error事件
E.根据URL地址,发起WebSocket连接
F.使用完WebSocket连接之后,主动断开连接

解析:A 选项描述错误。

在 WebSocket 连接开发中,通常没有“调用 Session.start 方法开启 metadata 数据输出”这样的步骤。

B 选项,创建 WebSocket 连接并返回对象,这是常见且正确的步骤。

C 选项,导入所需的 WebSocket 模块是开发的前置准备,正确。

D 选项,可选地订阅相关事件以便进行相应处理,合理。

E 选项,根据 URL 地址发起连接,符合流程。

F 选项,使用完后主动断开连接,有助于资源管理和避免不必要的消耗,正确。

综上所述,选择 A 选项。

多选题

42.哪些是持续部署最佳实践?
A.环境一致性:保持开发、测试、生产等环境的高度一致性。
B.手工部署:持续部署可以采用手工部署的方式发布软件:
1、有一份非常详尽的文档,该文档描述了执行步骤及每个步骤中易出错的地方;
2、以手工测试来确认该应用程序是否运行正确;
3、在发布时,常常会修正一些在发布过程中发现的问题。
C.监控和回滚机制:实时监控部署后的应用状态,如有问题及时回滚。
D.开发完成之后再向类生产环境部署:当软件被第一次部署到类生产环境(比如试运行环境)时,就是大部分开发工作完成时,至少是开发团队认为“该软件开发完成了”。
E.自动化部署流程:从代码提交到部署的整个流程应尽可能自动化。
F.手工配置管理:
1、直接修改生产环境上的配置来改变系统配置;
2、集群中各节点的行为有所不同;
3、靠人手工恢复环境。手动记载配置包括操作系统、应用服务器、关系型数据库管理系统、Web服务器或其他基础设施设置。
G.灰度发布:先在小部分用户或区域进行部署,观察没问题后再全面推广。

解析:以下是持续部署的最佳实践:

A. 环境一致性:保持开发、测试、生产等环境的高度一致性,这有助于减少因环境差异导致的问题,是持续部署的重要实践。

C. 监控和回滚机制:实时监控部署后的应用状态,如有问题及时回滚,能够降低风险,保障系统的稳定性。

E. 自动化部署流程:从代码提交到部署的整个流程应尽可能自动化,减少人为错误,提高效率。

G. 灰度发布:先在小部分用户或区域进行部署,观察没问题后再全面推广,可以降低新部署带来的风险。

B 选项中手工部署存在诸多问题,如依赖详尽的文档和手工测试,容易出错且效率低下,不符合持续部署的高效和自动化要求。

D 选项开发完成之后再向类生产环境部署不符合持续部署的快速和频繁部署的理念。

F 选项手工配置管理容易导致配置不一致、错误和难以维护,不符合持续部署的自动化和规范化要求。

综上所述,持续部署的最佳实践是 A、C、E、G 选项。

43.Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,以下关于Navigation组件说法正确的是()
A.Navigation的子页面可以来自不同的Module
B.Navigation只能在entry类型的Module中使用
C.Navigation子页面的根容器可以采用如Column、Row这些容器组件。
D.Navigation的页面显示模式有单页面、分栏和自适应三种显示模式

解析:以下是对每个选项的分析:

A 选项:Navigation 的子页面可以来自不同的 Module,这种说法是正确的。

B 选项:Navigation 并非只能在 entry 类型的 Module 中使用,该说法错误。

C 选项:Navigation 子页面的根容器通常不是采用如 Column、Row 这些容器组件,这种说法错误。

D 选项:Navigation 的页面显示模式有单页面、分栏和自适应三种显示模式,该说法正确。

综上所述,正确的是 A、D 选项。

44.使用ArkUI组件复用之后,还是没有显著提升列表滑动场景的性能,属于组件复用未生效可能的原因有?
A.页面嵌套了过多自定义组件。
B.没有在aboutToReuse更新关联的状态变量数据。
C.在aboutToReuse回调函数中更新了冗余的状态变量
D.复用的自定义组件中使用if等条件渲染语句导致结构不相同,未使用reuseId标记。

解析:以下是对每个选项的分析:

A 选项:页面嵌套过多自定义组件可能会影响性能,但不一定是组件复用未生效的直接原因。

B 选项:如果没有在 aboutToReuse 中更新关联的状态变量数据,可能导致组件复用出现问题,是未生效的可能原因之一。

C 选项:在 aboutToReuse 回调函数中更新冗余的状态变量可能影响性能,但不一定导致复用未生效。

D 选项:复用的自定义组件中使用条件渲染语句导致结构不同且未使用 reuseId 标记,这很可能导致组件复用未生效。

综上所述,属于组件复用未生效可能原因的是 B、D 选项。

45.以下代码片段哪几处违反了ArkTS语法规范。

function foo(value: number) {
  return value;
}

foo('');
foo(0);
foo(undefined);
foo(null);

A.foo(0);
B.foo(undefined);
C.foo(null);
D.foo(‘’)

解析:以下是对每个调用的分析:

函数 foo 定义时指定参数 value 的类型为 number

A 选项:foo(0) ,传递的是数字 0 ,符合 number 类型,没有违反语法规范。

B 选项:foo(undefined)undefined 不是数字类型,违反了语法规范。

C 选项:foo(null)null 不是数字类型,违反了语法规范。

D 选项:foo('') ,传递的是字符串 '' ,不是数字类型,违反了语法规范。

综上所述,违反 ArkTS 语法规范的是 B、C、D 选项。

46.下面代码符合ArkTS编程规范的是

A.
if (condition) {
  console.log('success');
}

B.
for (let idx = 0; idx < 5; ++idx)
  console.log(idx);

C.
let maxCount = 10, isCompleted = false;
let pointX, pointY;
pointX = 10; pointY = 0;

D.
let maxCount = 10;
let isCompleted = false;
let pointX = 0;
let pointY = 0;

解析:以下是对每个选项的分析:

A 选项:if 语句的使用符合常见的编程规范,代码块使用花括号包裹,是正确的写法。

B 选项:for 循环的写法不符合 ArkTS 的编程规范,循环体应该使用花括号包裹。

C 选项:变量声明和初始化的方式不符合规范,多个不同类型的变量应该分别声明和初始化。

D 选项:每个变量都单独声明和初始化,符合良好的编程规范。

综上所述,符合 ArkTS 编程规范的是 A、D 选项。

47.下面关于Node-API数据类型描述正确的是
A.napi_status:是一个枚举数据类型,表示Node-API接口返回的状态信息
B.napi_threadsafe_function_call_mode:该枚举类型定义了两个常量,用于指定在何时释放线程安全函数的回调函数
C.napi_threadsafe_function_release_mode:该枚举类型定义了两个常量,用于指定线程安全函数的调用模式
D.napi_env:用于表示Node-API执行时的上下文

解析:以下是对每个选项的分析:

A 选项:napi_status 确实是一个枚举数据类型,用于表示 Node-API 接口返回的状态信息,该选项正确。

B 选项:napi_threadsafe_function_call_mode 枚举类型定义的常量是用于指定线程安全函数的调用模式,而不是释放回调函数的时机,该选项错误。

C 选项:napi_threadsafe_function_release_mode 枚举类型定义的常量是用于指定在何时释放线程安全函数的资源,而不是指定调用模式,该选项错误。

D 选项:napi_env 用于表示 Node-API 执行时的上下文,该选项正确。

综上所述,描述正确的是 A、D 选项。

48.以下代码片段哪几个函数违反了ArkTS语法规范。

function foo1(value1?: number, value2: number) {
  if(value1 == undefined){
    return value2;
  }
    return value1 + value2;
}

function foo2(value1: number, value2?: number) {
  if (value2 == undefined) {
    return value1;
  }
  return value1 + value2;
}

function foo3(value: number, ...array: number[]) {
  return value;
}

function foo4( ...array: number[], value: number) {
  return value;
}

A.foo3
B.foo1
C.foo4
D.foo2

以下是对每个函数的分析:

foo1 函数:参数 value1 被标记为可选参数,其后的参数 value2 为必选参数,而必选参数不能跟随可选参数,所以不符合规范。

foo2 函数:参数 value1 为必选参数,value2 为可选参数,这种参数定义方式是符合规范的。

foo3 函数:使用剩余参数 ...array 且位于必选参数之后,这种定义方式是符合 ArkTS 语法规范的。

foo4 函数:剩余参数 ...array 位于必选参数 value 之前,这违反了 ArkTS 的语法规范,剩余参数应该放在最后。

综上所述,违反 ArkTS 语法规范的函数是foo1 foo4 ,选择A C 选项。

49.以下关于Taskpool和Worker的描述正确的是
A.Worker支持取消已发起的任务
B.TaskPool不支持线程复用
C.TaskPool支持设置任务的优先级
D.Worker的任务执行时长上限是无限制

解析:参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/taskpool-vs-worker-V5#实现特点对比

选:CD

50.下面关于混淆规则描述正确的是
A.-keep-global-name [,identifiers,…]:指定想保留的属性名
B.-keep-property-name [,identifiers,…]:指定要保留的顶层作用域的名称
C.-keep-file-name [,identifiers,…]:指定要保留的文件/文件夹的名称
D.-print-namecache filepath: 将名称缓存保存到指定的文件路径。

解析:以下是对每个选项的分析:

A 选项:-keep-global-class [,identifiers,...] 通常用于指定想保留的全局类名,而不是属性名,所以该选项错误。

B 选项:-keep-property-name [,identifiers,...] 这种规则通常不存在,所以该选项错误。

C 选项:-keep-filename [,identifiers,...] 用于指定要保留的文件/文件夹的名称,该选项正确。

D 选项:-print-namecache filepath 是将名称缓存保存到指定的文件路径,该选项正确。

综上所述,正确的是 C、D 选项。

51.处于安全因素考虑,ArkTS不支持以下哪些语法。
A.Object.entries()
B.with()
C.eval()
D.new Function(‘a’, ‘b’, ‘return a + b’)

解析:出于安全因素考虑,ArkTS 不支持 eval()with() 语法。

eval() 函数可以执行任意的 JavaScript 代码字符串,可能导致潜在的安全风险,如代码注入。

with() 语句在作用域方面可能导致难以预测和理解的行为,也可能引发一些安全和代码可读性的问题。

选项 A 中的 Object.entries() 是用于获取对象可枚举属性的键值对数组的方法,是合法和安全的。

选项 D 中通过 new Function() 创建函数的方式也不是 ArkTS 不支持的主要原因在于安全因素。

综上所述,选择 B、C 选项。

52.以下代码片段哪几处违反了ArkTS语法规范。

class Point {
  public x: number
  public y: number
  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
}

let p = new Point(1.0, 1.0);
delete p.x;
p.z = 2.0;
p.x = 'Hello!';

A.p.x = ‘Hello!’;
B.delete p.x;
C.p.z = 2.0;
D.let p = new Point(1.0, 1.0);

解析:以下是对每个操作的分析:

A 选项:p.x = 'Hello!' ,将字符串赋值给原本为数字类型的属性 x ,违反了类型规定,不符合语法规范。

B 选项:delete p.x ,在 ArkTS 中,不能使用 delete 操作符删除对象的属性,违反了语法规范。

C 选项:p.z = 2.0 ,给未在类中定义的属性 z 赋值,不符合类的属性定义规则,违反了语法规范。

D 选项:let p = new Point(1.0, 1.0) ,创建类的实例并初始化属性,这是符合 ArkTS 语法规范的。

综上所述,违反 ArkTS 语法规范的是 A、B、C 选项。

53.以下哪些实现方式可实现文本字号20的效果

A.
import { LengthMetrics, LengthUnit } from '@ohos.arkui.node'
@Entry
@Component
struct Index {
  fontStyleAttr: TextStyle = new TextStyle({fontSize:LengthMetrics.vp(20)});
  mutableStyledString: MutableStyledString = new MutableStyledString("hello", [{
    start: 0,
    length: 5,
    styledKey: StyledStringKey.FONT,
    styledValue: this.fontStyleAttr
  }]);
  controller: TextController = new TextController();

  async onPageShow() {
    this.controller.setStyledString(this.mutableStyledString)
  }

  build() {
    Column() {
      // 显示属性字符串
      Text(undefined, { controller: this.controller })
    }.width('100%')
  }
}

B.
// xxx.ets
@Entry
@Component
struct Index {
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
      Text('This is the text with the height adaptive policy set')
        .width('80%')
        .height(90)
        .minFontSize(20)
    }.width('100%').height(250).padding({ left: 35, right: 35, top: 35 })
  }
}

C.
// xxx.ets
@Entry
@Component
struct Index {
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
      // 文本水平方向对齐方式设置
      // 单行文本
      Text('TextAlign set to Center.')
        .textAlign(TextAlign.Center)
        .fontSize(20)
        .border({ width: 1 })
        .padding(10)
        .width('100%')
    }.height(600).width(350).padding({ left: 35, right: 35, top: 35 })
  }
}

D.
@Entry
@Component
struct SpanExample {
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
      Text() {
        Span('span letter spacing')
          .letterSpacing(3)
          .fontSize(20)
      }.fontSize(30)
    }.width('100%').height(250).padding({ left: 35, right: 35, top: 35 })
  }
}

解析:以下选项中可实现文本字号 20 的效果的是:

  • A 选项:通过 new TextStyle({fontSize:LengthMetrics.vp(20)}) 为文本设置了字号为 20。
  • C 选项:使用 .fontSize(20) 直接设置了文本的字号为 20。
  • D 选项:在 Span 中通过 .fontSize(20) 设置了字号为 20。

B 选项中的 minFontSize(20) 是设置了最小字号为 20,而不是直接设置当前文本的字号为 20。

综上所述,可实现文本字号 20 效果的是 A、C、D 选项。

54.如果想让grid上的捏合手势手势生效,而不跟grid上的滚动手势形成冲突,.xxxx?手势接口应该怎么配置?

Grid() {
        ForEach(this.numbers, (day: string) => {
          ForEach(this.numbers, (day: string) => {
            GridItem() {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width('100%')
                .height(80)
                .textAlign(TextAlign.Center)
            }
          }, (day: string) => day)
        }, (day: string) => day)
      }
      .columnsTemplate('1fr '.repeat(this.columns))
      .columnsGap(10)
      .rowsGap(10)
      .width('90%')
      .scrollBar(BarState.Off)
      .backgroundColor(0xFAEEE0)
      .height('100%')
      .cachedCount(3)
      // 切换列数item位置重排动画
      .animation({
        duration: 300,
        curve: Curve.Smooth
      })
      .xxxx?(
        PinchGesture()
          .onActionEnd((event: GestureEvent) => {
            console.info('end scale:' + event.scale)
            // 手指分开,减少列数以放大Item,触发阈值可以自定义,示例为2
            if (event.scale > 2) {
              this.columns--
            } else if (event.scale < 0.6) {
              this.columns++
            }
            // 可以根据设备屏幕宽度设定最大和最小列数,此处以最小1列最大4列为例
            this.columns = Math.min(4, Math.max(1, this.columns));
            AppStorage.setOrCreate('columnsCount', this.columns)
          })
      )

A.gesture
B.priorityGesture
C.parallelGesture
D.GesureGroup

解析:选B、C,参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-gesture-events-binding-V5

55.Image组件以下哪些方式可显示图片?

A.
@Entry
@Component
struct ImageExample {
  build() {
    Column({ space: 10 }) {
      Image("https://www.example.com/xxx.png")
        .width(100)
        .height(100)
    }
  }
}


B.
import { DrawableDescriptor } from '@ohos.arkui.drawableDescriptor'

@Entry
@Component
struct ImageExample {
  private resManager = getContext().resourceManager

  build() {
    Row() {
      Column() {
        Image((this.resManager.getDrawableDescriptor($r('app.media.drawable').id) as DrawableDescriptor))
      }.height('50%')
    }.width('50%')
  }
}


C.
@Entry
@Component
struct ImageExample {
  build() {
    Column({ space: 10 }) {
      Image($r('app.media.earth'))
        .width(100)
        .height(100)
    }
  }
}


D.
import image from '@ohos.multimedia.image'
@Entry
@Component
struct ImageExample {
  @State imagePixelMap: image.PixelMap | undefined = undefined

  async aboutToAppear() {
    this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.app_icon'))
  }

  build() {
    Column() {
      Image(this.imagePixelMap)
        .width(200)
        .height(200)
    }
  }
  private async getPixmapFromMedia(resource: Resource) {
    let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({
      bundleName: resource.bundleName,
      moduleName: resource.moduleName,
      id: resource.id
    })
    let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength))
    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
      desiredPixelFormat: image.PixelMapFormat.RGBA_8888
    })
    await imageSource.release()
    return createPixelMap
  }
}

解析:以下选项中的方式都可以让 Image 组件显示图片:

  • A 选项:通过网络图片地址 https://www.example.com/xxx.png 进行显示,并设置了宽度和高度。
  • B 选项:使用资源管理器获取的 DrawableDescriptor 来显示图片。
  • C 选项:通过资源 ID $r('app.media.earth') 来显示图片,并设置了宽度和高度。
  • D 选项:通过加载资源并进行一系列处理后得到的 image.PixelMap 来显示图片,并设置了宽度和高度。

综上所述,A、B、C、D 选项的方式都可让 Image 组件显示图片。

56.依次点击A、B、C、D四个按钮,其中不会触发UI刷新的是:

@Entry
@Component
struct Index {
  @State count: number = 0;
  @State @Watch('onValueChange') value: number = 50;

  onValueChange() {
    this.count = this.value;
  }
  build() {
    Column() {
      Text(`${this.count}`)
      Button("A")
        .onClick(() => {
          this.count = 0;
        })
      Button("B")
        .onClick(() => {
          for (let i = 0; i < 1000; i++) {
            this.count = i;
          }
          for (let i = 1000; i > 0; i--) {
            this.count = i;
          }
          this.count--;
        })
      Button("C")
        .onClick(() => {
          this.value = 100;
        })
      Button("D")
        .onClick(() => {
          setInterval(()=>{
            this.count++;
          }, 1000)
        })
    }
  }
}

A.B
B.A
C.C
D.D

答案:选AB

57.HarmonyOS应用开发者小张,正在利用DevEco Studio进行一款复杂应用的UI界面调试。小张了解到ArkUI Inspector是DevEco Studio内置的一项强大工具,能够显著提升UI调试效率。基于ArkUI Inspector的特性描述,下列哪些描述是正确的
A.性能监控:提供详细的UI渲染性能指标,帮助开发者识别布局瓶颈和渲染效率问题,从而优化应用性能
B.交互式组件选择:用户既可以在组件树视图中选择组件,使UI界面上对应组件高亮显示并展示其属性详情;也可以直接在UI布局显示界面上点击选择组件
C.UI效果查看:开发者能够查看连接真机上运行的应用程序的UI显示效果,页面组件树结构,以及选中组件的属性信息
D.UI快照管理:支持导出应用的UI界面为快照图片,并允许这些快照被导入回ArkUI Inspector中,便于离线分析或分享讨论UI设计方案

解析:以下是对每个选项的分析:

A 选项:ArkUI Inspector 能够提供性能监控,包括详细的 UI 渲染性能指标,帮助开发者识别布局瓶颈和渲染效率问题以优化应用性能,该描述正确。

B 选项:ArkUI Inspector 具有交互式组件选择的功能,用户可以在组件树视图中选择组件以使对应组件在 UI 界面高亮显示并展示属性详情,也可以直接在 UI 布局显示界面上点击选择组件,该描述正确。

C 选项:开发者不仅能在模拟器中,还能查看连接真机上运行的应用程序的 UI 显示效果、页面组件树结构以及选中组件的属性信息,该描述正确。

D 选项:ArkUI Inspector 支持导出应用的 UI 界面为快照图片,并允许这些快照被导入回进行分析,便于离线分析或分享讨论 UI 设计方案,该描述正确。

综上所述,A、B、C、D 选项的描述都是正确的。

58.某个应用的启动框架配置文件详细信息如下,以下说法正确的是:

{

  "startupTasks": [

    {

      "name": "StartupTask_001",

      "srcEntry": "./ets/startup/StartupTask_001.ets",

      "dependencies": [

        "StartupTask_002",

        "StartupTask_003"

      ],

      "runOnThread": "taskpool",

      "waitOnMainThread": false

    },

    {

      "name": "StartupTask_002",

      "srcEntry": "./ets/startup/StartupTask_002.ets",

      "dependencies": [

        "StartupTask_004"

      ],

      "runOnThread": "taskpool",

      "waitOnMainThread": false

    },

    {

      "name": "StartupTask_003",

      "srcEntry": "./ets/startup/StartupTask_003.ets",

      "runOnThread": "taskpool",

      "waitOnMainThread": false

    },

    {

      "name": "StartupTask_004",

      "srcEntry": "./ets/startup/StartupTask_004.ets",

      "runOnThread": "taskpool",

      "waitOnMainThread": false

    },

    {

      "name": "StartupTask_005",

      "srcEntry": "./ets/startup/StartupTask_005.ets",

      "runOnThread": "mainThread",

      "waitOnMainThread": true

    },

    {

      "name": "StartupTask_006",

      "srcEntry": "./ets/startup/StartupTask_006.ets",

      "runOnThread": "mainThread",

      "waitOnMainThread": false,

      "excludeFromAutoStart": true

    }

  ],

  "configEntry": "./ets/startup/StartupConfig.ets"

}

A.StartupTask_003会在StartupTask_004之后执行
B.StartupTask_006会在AbilityStage的onCreate前初始化完成
C.StartupTask_001会在StartupTask_004之后执行;
D.StartupTask_005会在主线程执行

解析:选BCD,参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-startup-V5#编写启动框架配置文件

59.使用如下的代码去启动一个ability时,哪种skills定义的组件能够被匹配到:

let want = {
  "uri" : "https://www.test.com:8080/query/books",
  "type" : "text/plain"
}

context.startAbility(want).then((data))=> {
  console.log(TAG + "startAbility success");
}).catch((err))=> {
  console.log(TAG + "startAbility failed.");
}

A.
"skills": [
  {
    "uris":[
      {
        "scheme": "https",
        "host": "www.test.com",
        "pathStartWith" : "query/books",
        "type" : "text/*"        
      }
    ]
  }
]

B.
"skills": [
  {
    "uris":[
      {
        "scheme": "https",
        "type" : "text/*"        
      }
    ]
  }
]

C.
"skills": [
  {
    "uris":[
      {
        "scheme": "https",
        "host": "www.test.com",
        "type" : "text/plain"        
      }
    ]
  }
]

D.
"skills": [
  {
    "uris":[
      {
        "scheme": "https",
        "host": "www.test.com",
        "pathStartWith" : "query/books",
        "type" : "text/plain"        
      }
    ]
  }
]

解析:选BC,参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/explicit-implicit-want-mappings-V5#want参数的uri和type匹配规则

60.在基于Stage模型开发的应用项目代码下,都存在一个app.json5配置文件,用于配置应用的全局信息,以下app.json5配置文件错误的是

A.
{
  "app": {
    "bundleName": "com.example.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.2",
    "icon": "$media:app_icon",
    "label": "$string:app_name",
    "bundleType": "app"
  }
}

B.
{
  "app": {
    "bundleName": "com.example.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.2",
    "icon": "$media:app_icon",
    "label": "$string:app_name"
  }
}

C.
{
  "app": {
    "bundleName": "com.example.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.2",
    "icon": "$media:app_icon",
    "label": "app_name",
    "bundleType": "app"
  }
}

D.
{ 
"app": { 
   "bundleName": "com.example.myapplication", 
   "vendor": "example", "versionCode": 1000000, 
   "icon": "$media:app_icon", 
   "label": "$string:app_name",
   "bundleType": "app" 
   } 
}

解析:选CD。C:【label】字段的值需要引用 D:缺少字段【versionName】参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-configuration-file-V5#配置文件标签

08-03 09:28