鸿蒙面试 2025-01-10
写了鉴权工具,你在项目中申请了那些权限?(常用权限)
-
位置权限 :
ohos.permission.LOCATION_IN_BACKGROUND:允许应用在后台访问位置信息。 ohos.permission.LOCATION:允许应用访问精确的位置信息。 ohos.permission.APPROXIMATELY_LOCATION:允许应用访问大致的位置信息。
-
相机权限 :
ohos.permission.CAMERA:允许应用访问相机设备。
-
麦克风权限 :
ohos.permission.MICROPHONE:允许应用访问麦克风设备。
-
通讯录权限 :
ohos.permission.READ_CONTACTS:允许应用读取通讯录。 ohos.permission.WRITE_CONTACTS:允许应用写入通讯录。
-
日历权限 :
ohos.permission.READ_CALENDAR:允许应用读取日历数据。 ohos.permission.WRITE_CALENDAR:允许应用写入日历数据。
-
运动数据权限 :
ohos.permission.ACTIVITY_MOTION:允许应用访问运动数据。此权限不支持在2in1设备上申请。
-
身体传感器权限 :
ohos.permission.READ_HEALTH_DATA:允许应用读取健康数据。此权限仅穿戴设备可申请。
-
图片和视频权限 :
ohos.permission.WRITE_IMAGEVIDEO:允许应用写入图片和视频。 ohos.permission.READ_IMAGEVIDEO:允许应用读取图片和视频。
-
音乐和音频权限 :
ohos.permission.WRITE_AUDIO:允许应用写入音频文件。 ohos.permission.READ_AUDIO:允许应用读取音频文件。
-
跨应用关联权限 :
ohos.permission.APP_TRACKING_CONSENT:允许应用进行跨应用跟踪。
-
多设备协同权限 :
ohos.permission.DISTRIBUTED_DATASYNC:允许应用在多设备之间同步数据。
-
蓝牙权限 :
ohos.permission.ACCESS_BLUETOOTH:允许应用访问蓝牙设备。
-
剪切板权限 :
ohos.permission.READ_PASTEBOARD:允许应用读取剪切板数据。
-
文件夹权限 :
ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY:允许应用读写下载目录。 ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY:允许应用读写文档目录。此权限仅2in1设备可申请。
使用安全控件的话可以免申请权限?为啥不考虑使用安全控件?
使用安全控件确实可以在某些情况下免除你在鸿蒙系统中申请权限的需要。安全控件是一种系统提供的ArkUI组件,它们允许应用在用户点击后自动授权,无需额外的弹窗授权。这种方式不仅简化了开发者和用户的操作,还能够基于场景化授权,匹配用户的真实意图,从而减少弹窗打扰,提升用户体验。
安全控件的主要优点包括:
- 用户掌握授权时机 :用户可以在需要时才进行授权,授权范围也最小化。
- 简化操作 :开发者不必向应用市场申请权限1。
- 隐私合规 :安全控件坚持仅采集实现业务功能所必须的个人数据1。
目前,系统提供了三类安全控件:
- 粘贴控件(PasteButton) :对应剪贴板读取特权,适用于需要读取剪贴板的场景1。
- 保存控件(SaveButton) :对应媒体库写入特权,适用于需要保存文件到媒体库的场景1。
- 位置控件(LocationButton) :对应精准定位特权,适用于需要在前台短暂使用位置信息的场景。
例如,在聊天界面发送实时定位信息的场景中,你可以直接使用位置控件来获得临时的精准定位授权,这样就可以避免长时间使用位置信息或后台使用位置信息的情况,从而满足权限最小化和提升隐私体验的要求2。
鉴于这些优势,使用安全控件成为了一种优选的解决方案,尤其是在应用不需要持续或后台访问敏感信息的情况下。这样不仅可以提高应用的隐私保护水平,还可以增强用户的信任和使用体验。
约束与限制
安全控件因其自动授权的特性,为了保障用户的隐私不被恶意应用获取,针对安全控件作了很多的限制。应用开发者需保证安全控件在应用界面上清晰可见、用户能明确识别,防止因覆盖、混淆等因素导致授权失败。
当因控件样式不合法导致授权失败的情况发生时,请开发者检查设备错误日志,过滤关键字"SecurityComponentCheckFail"可以获取具体原因。
可能会导致授权失败的问题(包括但不限于):
-
字体、图标尺寸过小。
-
安全控件整体尺寸过大。
-
字体、图标、背景按钮的颜色透明度过高。
-
字体或图标与背景按钮颜色过于相似。
-
安全控件超出屏幕、超出窗口等,导致显示不全。
-
安全控件被其他组件或窗口遮挡。
-
安全控件的父组件有类似变形模糊等可能导致安全控件显示不完整的属性。
扫描二维码需要相机权限吗?拍照需要相机权限吗?
需要
在鸿蒙(HarmonyOS)开发中,使用相机进行扫码和拍照确实需要申请相机权限。这是因为相机操作涉及到用户的隐私和安全,因此应用在使用相机前必须获得用户的明确授权。
具体来说,对于相机权限的申请,您需要在应用的module.json5
文件中配置相机权限,如下所示:
"permissions": [ "ohos.permission.CAMERA" ]
这行配置表示您的应用请求使用相机的权限。在应用运行时,您还需要通过代码请求用户授权,可以使用以下代码片段:
import { requestPermissionsFromUser } from '@ohos.ability';const permissions = ['ohos.permission.CAMERA'];
const result = await requestPermissionsFromUser(permissions);
if (result['ohos.permission.CAMERA'] === 'authorized') {console.log('Camera permission authorized');
} else {console.log('Camera permission denied');
}
这段代码会弹出一个授权对话框,让用户决定是否授予应用相机权限。只有当用户同意后,应用才能使用相机进行扫码或拍照。
因此,无论是进行二维码扫描还是拍照,您的应用都需要先确保已经获得了相机权限。这是保障用户隐私和应用功能正常运行的重要步骤。
不需要
系统通过提供系统Picker和安全控件两种方式,使得应用能够便捷地访问系统资源。这两种方法均依赖于系统的独立进程来实现,当应用拉起系统Picker或展示安全控件时,必须依赖用户的主动操作来获取资源或结果。这一流程避免了应用额外申请权限,同时,由于用户的积极参与,进一步增强了用户隐私和安全的保护。
系统Picker
系统Picker是拉起系统资源的一种方式,由于系统Picker已经获取了对应权限的预授权,开发者使用系统Picker时,无需再次申请权限也可临时受限访问对应的资源。
使用系统Picker组件拉起系统应用的场景主要有:联系人Picker(Contacts Picker),地图Picker,相机Picker(Camera Picker),扫码Picker,卡证识别Picker,文档扫描Picker,文件Picker,音频Picker和照片Picker(PhotoViewPicker)等,详细可参考拉起系统应用。
安全控件
安全控件是系统提供的一组系统实现的ArkUI组件,应用集成这类组件就可以实现在用户点击后自动授权,而无需弹窗授权。它们可以作为一种“特殊的按钮”融入应用页面,实现用户点击即许可的设计思路。
目前系统提供三类安全控件:粘贴控件(PasteButton)、保存控件(SaveButton)、位置控件(LocationButton)。
使用场景示例
以下列举了三个优先使用系统Picker或者安全控件的场景:
- 读写媒体库图片或视频:
- 推荐方案(无需申请权限):使用PhotoViewPicker读取媒体库的图片与视频;使用安全控件中的保存控件保存媒体库的图片与视频。
- 申请权限方案:申请受限权限ohos.permission.READ_IMAGEVIDEO或ohos.permission.WRITE_IMAGEVIDEO读取媒体库的图片与视频。
- 拉取系统相机拍照录制:
- 推荐方案(无需申请权限):仅是需要拉起系统相机拍摄一张照片、录制一段视频,可直接使用CameraPicker,无需申请相机权限。
- 申请权限方案:开发一个相机应用(或是在应用内开发相机模块)时,需按相机开发指导在开发前做好申请权限的准备。
- 访问当前位置:
- 推荐方案(无需申请权限):应用仅需要在部分前台场景短暂地访问位置信息(例如定位城市、打卡、分享位置等),不需要长时间使用。此时,可以直接使用安全控件中的位置控件,免去权限申请和权限请求等环节,获得临时授权,满足权限最小化,提升用户的隐私体验。
- 申请权限方案:如果需要长时间使用或是在后台使用位置信息,建议申请位置权限。
华为一键登入认证需要怎么做?
华为一键登录认证主要涉及以下几个步骤:
-
集成登录组件 :
- 在您的应用中集成华为账号登录组件。这可以通过添加
LoginWithHuaweiIDButton
按钮来实现,该按钮支持一键登录功能。
- 在您的应用中集成华为账号登录组件。这可以通过添加
-
配置权限 :
- 在应用后台配置中,您需要申请
quickLoginMobilePhone
(华为账号一键登录)的scope权限。这是实现一键登录的前提条件。
- 在应用后台配置中,您需要申请
-
用户交互设计 :
- 按照华为的设计规范,设计一键登录的用户体验(UX)。这包括按钮的样式设计和页面布局,确保符合华为账号一键登录的视觉和体验标准。
-
处理登录逻辑 :
- 当用户点击一键登录按钮后,应用会检查华为账号的登录状态。如果已经登录,应用将解析出用户的
UnionID
、OpenID
和手机号码。 - 如果用户在90天内没有验证记录,系统将触发短信验证流程,以确保手机号的有效性。
- 当用户点击一键登录按钮后,应用会检查华为账号的登录状态。如果已经登录,应用将解析出用户的
-
协议处理 :
- 用户在使用一键登录前,必须同意《华为账号用户认证协议》1。您可以引导用户查看协议内容,并在用户同意后继续登录流程。
-
服务器配置 :
- 应用服务器在获取华为账号绑定的手机号码时,必须确保服务器部署在中国大陆境内,因为该项服务当前仅限中国大陆用户使用。
通过以上步骤,您的应用就可以实现华为账号的一键登录功能,提供给用户快速、便捷的登录体验。
华为一键登入前端能获取到手机号码吗?
在华为账号一键登录功能中,前端确实能够获取到用户的手机号码。这一功能是通过华为的Account Kit实现的,它允许开发者在用户点击一键登录按钮后,获取用户绑定到华为账号的手机号码。
具体的实现方式如下:
- 用户点击一键登录按钮后,系统会检查用户在最近90天内是否有短信验证通过的记录。如果有,則直接返回手机号码;如果没有,系统将触发默认的短信验证流程。
- 这一过程中,开发者可以通过设置相应的回调函数来处理验证结果,例如在用户同意协议并完成登录后,可以使用
continueLogin(callback)
方法来处理登录结果。
注意这里虽然获取到了手机号码,但是是匿名手机号码 例如 183******58
flutter怎么适配安卓和IOS?
Flutter 能够高效适配安卓(Android)与 iOS 平台,主要得益于以下几个关键要素:
- 跨平台框架设计
- 统一的编程语言:Flutter 使用 Dart 语言进行开发,它无需针对不同平台学习 Objective-C、Swift(iOS) 或 Java、Kotlin(Android)。开发者用一套代码,就能在两大主流移动平台构建应用,节省大量人力与学习成本。例如开发一款简单的待办事项应用,从创建任务列表、添加删除任务的逻辑,到界面布局与交互,代码只需编写一次。
- 自绘引擎:Flutter 自带了一套高性能的自绘引擎,不依赖于原生系统控件。无论是在安卓的 Material Design 风格,还是 iOS 的扁平简约风格下,它能直接在画布上绘制出符合对应平台设计规范的 UI 元素,摆脱原生控件适配难题,像绘制一个自定义的渐变按钮,Flutter 可以精准呈现,不受原生系统限制。
- 平台适配插件
- 官方插件:Flutter 官方提供海量的插件库,覆盖常见的功能,如摄像头调用、地理位置获取、蓝牙连接等。针对安卓与 iOS 平台的特性差异,这些插件内部已做了适配处理。以地图插件为例,它能无缝对接谷歌地图(Android)和苹果地图(iOS),开发者使用时只需按统一接口操作,不必操心底层适配。
- 社区插件:活跃的 Flutter 社区持续贡献丰富插件,补充官方遗漏的小众或新需求场景。当新的 iOS 系统特性发布,社区开发者会迅速反应,更新插件适配新功能,其他开发者拿来就能用,加快项目适配新平台特性的速度。
- 遵循设计规范
- 安卓 Material Design:对于安卓平台,Flutter 提供了遵循 Material Design 规范的组件库,开发者可以轻松组合出具有安卓风格的页面,像带水波纹特效的按钮、多层卡片式布局,让应用融入安卓生态。
- iOS Human Interface Guidelines:对应 iOS,Flutter 同样能塑造贴合 iOS 设计理念的界面,如简洁大气的导航栏样式、细腻的动画过渡,确保应用在 iOS 设备上的用户体验符合苹果官方标准。
- 编译打包流程
- 差异化配置:Flutter 项目的构建脚本支持为安卓与 iOS 分别设置特定参数,比如安卓的不同应用市场渠道包配置、iOS 的 App Store 上架证书配置等。开发者可以在编译时精细调整,确保生成的应用包符合对应平台的上架、分发要求。
- 多平台测试:Flutter CLI 工具方便开发者在安卓模拟器、真机以及 iOS 模拟器、真机上快速测试,通过多轮反复测试,排查因平台差异隐藏的兼容性问题,从布局错乱到功能异常,尽早发现并修复。
安卓的四大组件?
安卓的四大组件分别是 Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器)以及 Content Provider(内容提供者),它们各自发挥着关键作用,协同构建起功能丰富的安卓应用:
- Activity(活动)
- 用户交互核心:作为安卓应用中直接与用户交互的可视化界面单元,每一个 Activity 通常对应一屏显示内容,像登录界面、主菜单、商品详情页等。它接收并响应用户的各类操作,例如触摸屏幕、按键点击,借此驱动页面跳转、数据更新、输入处理等交互流程。用户打开购物 APP,首先映入眼帘的首页 Activity,浏览商品时点击图片进入对应的商品详情 Activity,这一系列交互都发生在 Activity 层面。
- 生命周期管理:有着严谨的生命周期,包括创建(onCreate)、启动(onStart)、恢复(onResume) 、暂停(onPause)、停止(onStop)、销毁(onDestroy)等阶段。开发者依据这些阶段精准把控资源分配与回收,比如在 onCreate 阶段初始化界面布局与数据,onDestroy 阶段释放不再使用的资源,防止内存泄漏。
- Service(服务)
- 后台持续运行:专注于在后台长时间执行特定任务,无需可视化界面。典型场景如音乐持续播放、文件后台下载、实时数据同步等。即使用户切换到其他 APP,对应的服务依然可以稳定运行,维持业务的连贯性,用户开启音乐播放服务后,即便切出去浏览新闻资讯,音乐也不停歇。
- 跨组件协作:它能够与其他组件配合,通过 Intent 启动,也可以与 Activity、Broadcast Receiver 互动。例如,Activity 可以启动一个 Service 来执行耗时任务,之后通过广播接收器接收 Service 完成任务的反馈,实现不同组件间的接力协作。
- Broadcast Receiver(广播接收器)
- 消息监听响应:负责监听系统或应用发出的广播消息,安卓系统在众多关键事件节点,如开机、网络连接变化、电量不足等,都会发送广播;应用自身也能按需自定义广播。广播接收器捕捉到广播后,即刻执行预设的响应动作,手机电量低时,系统广播发出,电量预警类 APP 中的广播接收器收到信号,便及时提醒用户充电。
- 系统集成与拓展:借助广播接收器,应用得以深度融入安卓系统生态,拓展功能边界。例如,安装新应用时系统广播触发,某些文件管理类 APP 借此广播可自动扫描新安装应用相关文件,实现智能管理。
- Content Provider(内容提供者)
- 数据共享桥梁:充当不同安卓应用间数据共享的媒介,把自身应用的数据以安全、可控的方式提供给其他授权应用访问。常见的,通讯录应用通过 Content Provider 将联系人数据开放,第三方短信、社交 APP 获取授权后,就能读取联系人,实现诸如短信群发、好友推荐等功能。
- 数据封装与访问控制:它将数据封装成统一格式,配套设置访问权限规则,既保障数据拥有者的权益,也让有需求的应用合规获取数据,促进安卓应用间的数据流通与协同。 。
有了解Handler吗?Handler是什么?
在安卓开发中,Handler
是一个极为关键的类,用于实现线程间通信,尤其是在处理主线程(UI 线程)与子线程交互时必不可少,主要体现在以下几方面:
- 基本原理
Handler
关联着MessageQueue
(消息队列)与Looper
(循环器)。MessageQueue
是一个存放Message
(消息)的队列,按先进先出原则排列,用于暂存那些等待被处理的消息;Looper
则持续不断地从这个队列里取出消息,并把消息分发给对应的Handler
去处理。每个线程默认只有一个Looper
,主线程的Looper
在安卓应用启动时就自动创建好了,而子线程若要使用Handler
,往往得手动创建Looper
。
- 作用
- 助力 UI 更新:安卓规定,耗时操作不能在主线程执行,否则会阻塞 UI,造成界面卡顿甚至 ANR(Application Not Responding,应用无响应)。当子线程完成耗时任务,如网络下载、数据库查询后,可将结果封装进
Message
,借助Handler
发送到主线程的MessageQueue
。主线程的Looper
会从队列中取出该消息,再由对应的Handler
处理,从而安全地更新 UI 。例如,子线程下载好一张图片后,把图片数据通过Handler
传递给主线程,主线程更新 ImageView 来展示图片。 - 线程间协调:不仅是子线程向主线程汇报,
Handler
也用于多线程间的信息传递与任务调度。不同子线程之间可以通过共享的Handler
发送和接收消息,让它们的工作协同起来,有条不紊地完成复杂项目,像是在一个多线程处理多媒体文件的项目里,音频处理线程与视频处理线程靠Handler
沟通进度、同步状态。
- 助力 UI 更新:安卓规定,耗时操作不能在主线程执行,否则会阻塞 UI,造成界面卡顿甚至 ANR(Application Not Responding,应用无响应)。当子线程完成耗时任务,如网络下载、数据库查询后,可将结果封装进
- 使用方式
- 创建与发送消息:首先得创建
Handler
对象,通常是在主线程创建,并重写handleMessage
方法,用于定义收到消息后的处理逻辑。接着,在子线程生成Message
,通过Handler
的sendMessage
或post
方法把消息发送出去 。例如:Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {// 处理消息,msg里携带了数据super.handleMessage(msg);} };new Thread(new Runnable() {@Overridepublic void run() {Message message = Message.obtain();// 设置消息内容handler.sendMessage(message);} }).start();
在上述代码中,先定义
Handler
,子线程获取Message
后发送给主线程的Handler
处理。
- 创建与发送消息:首先得创建
Handler
、Message
,Looper
与MessageQueue 之间的关系?
Handler、Message、Looper 与 MessageQueue 在安卓开发的线程间通信机制里紧密协作,各自承担独特功能,共同构成一个高效的信息流转体系:
- Message
- 数据载体:它是整个通信流程的 “包裹”,用来承载各式各样的数据。无论是简单的整数、字符串,还是复杂的自定义对象,都能封装进
Message
。例如,子线程完成网络数据下载任务后,把下载的数据封装到Message
里,以便传递给其他线程处理。Message
自身带有一些属性字段,像是what
,开发者可以为其赋值,以此区分不同类型的消息,方便接收方针对性处理。
- 数据载体:它是整个通信流程的 “包裹”,用来承载各式各样的数据。无论是简单的整数、字符串,还是复杂的自定义对象,都能封装进
- MessageQueue
- 消息队列:充当 “信息仓库”,是一个按先进先出(FIFO)原则组织的队列。所有待处理的
Message
都会被依次排入这个队列,无论消息来自哪个线程。这就好比银行营业厅的排队叫号系统,众多客户(消息)按先来后到顺序等待被服务(处理)。它负责暂存众多Message
,保证消息处理的有序性。
- 消息队列:充当 “信息仓库”,是一个按先进先出(FIFO)原则组织的队列。所有待处理的
- Looper
- 消息循环器:关联着
MessageQueue
,是驱动整个消息处理流程的 “引擎”。Looper
会不断地从MessageQueue
里取出Message
,然后将其分发给对应的Handler
去处理。每个线程默认情况下只会有一个Looper
,主线程的Looper
在安卓应用启动时便自动创建完成;而子线程如果要启用Handler
,多数时候得手动搭建Looper
体系,否则无法正常收发消息。Looper
持续运转,不停地从队列中捞出消息,维持信息处理的动态循环。
- 消息循环器:关联着
- Handler
- 消息处理器:一方面,
Handler
是消息的 “投递员”,负责把Message
发送到对应的MessageQueue
。比如,子线程中有重要数据要传递给主线程更新 UI,就通过子线程创建的Handler
把封装好数据的Message
排入主线程的MessageQueue
。另一方面,Handler
也是消息的 “接收站”,它定义了handleMessage
方法,当Looper
把从MessageQueue
中取出的Message
转交给Handler
时,就会触发该方法,进而处理消息内容,完成从消息发送、排队、提取到最终处理的完整闭环。
- 消息处理器:一方面,
总结来说,Message
承载具体数据进入MessageQueue
排队等待,Looper
驱动循环从队列中提取Message
,再由Handler
完成收发与处理,它们协同运作,保障安卓应用多线程间有条不紊地通信。
鸿蒙状态管理的装饰器?
- @State
- 功能:在使用鸿蒙的声明式开发范式时,
@State
是极为重要的标识。当一个变量被标注为@State
,意味着这个变量用于保存组件的本地状态,它的任何改变都会触发组件的重新渲染。例如在一个简单的计数器组件里,把记录当前计数值的变量标记成@State
,每次点击增加或减少按钮改变这个值时,组件会迅速响应,更新界面显示的数字,精准呈现最新状态。 - 原理:鸿蒙的 ArkUI 框架依赖这种机制追踪状态变化。被
@State
修饰的变量发生变更,框架能够感知,随即启动重新构建受影响的 UI 部分流程,避免了不必要的全页面刷新,优化性能的同时,也让 UI 与数据状态紧密同步。
- 功能:在使用鸿蒙的声明式开发范式时,
- @Prop
- 功能:用于父子组件之间的数据传递与状态关联。如果父组件有某个数据需要传递给子组件,将该数据通过
@Prop
修饰后传递下去,子组件接收后就能基于这份数据展示内容或者执行逻辑。并且,子组件对这个数据的修改,也能反向通知父组件,维持父子组件间状态的协同更新。打个比方,父组件是一个商品列表,把选中商品的索引用@Prop
传给子组件(商品详情展示框 ),子组件里切换商品详情时,父组件也能同步知晓,更新列表选中状态。 - 优势:通过
@Prop
构建起清晰高效的父子组件交互通道,简化跨组件状态同步的复杂程度,提升代码可读性与可维护性,降低因状态不同步引发的 bug 出现概率。
- 功能:用于父子组件之间的数据传递与状态关联。如果父组件有某个数据需要传递给子组件,将该数据通过
- @Link
- 功能:建立父子组件间的双向数据绑定通道。无论是父组件数据变动影响子组件显示,还是子组件对数据的修改,都能实时反馈给父组件,让二者的数据状态时刻保持同步,双向互通。
- 协同:和普通单向传递数据的机制相互补充,在父子组件交互场景下,要是数据需频繁来回变动,@Link 简化操作,无需手动编写过多更新逻辑,两边数据自动协同,提升开发效率与交互响应速度。
- @Provide 与 @Consume
- 功能:@Provide 负责将某个状态变量公开,使其成为全局或局部范围内可共享的 “资源池”;@Consume 则像一个 “取水口”,组件添加该装饰器就能获取、使用被提供的状态,让状态能跨多层级、多组件流通。
- 协同:二者配合打破组件层级束缚,不同深度嵌套的组件依靠它们能基于共享状态协同运作,一处状态变更,各处相关消费该状态的组件自动更新,维持应用整体状态一致性。
- @ObjectLink
- 功能:聚焦于对象属性层面的变化追踪与同步。只要被观察对象的属性值出现变动,与之绑定、添加此装饰器的 UI 组件立刻知晓,随即更新展示内容,精准呈现对象最新状态。
- 协同:搭配常规的对象操作逻辑,当业务频繁更新对象属性时,它保障 UI 与对象状态无缝衔接,无需额外干预,就能让相关 UI 与对象状态协同变化,优化用户界面实时响应效果。
- @Observerd
- 功能:自动监测被修饰变量或对象的属性改变,一旦发生变化,迅速触发相关 UI 的更新流程,让 UI 始终贴合数据最新情况,实现数据驱动 UI 更新。
- 协同:融入整体数据处理与 UI 构建流程,和其他改变数据的操作协同,例如用户输入、后台数据推送,确保数据更新瞬间,UI 也能及时跟进,维持数据与展示的连贯性。
-
@StorageLink
- 功能:它主要用于将组件内的状态与持久化存储相关联。当被标记的变量发生变化时,不仅会更新 UI,还会同步更新对应的存储数据,保障数据的持久保存。例如在一个笔记应用里,用户编辑笔记内容,被 @StorageLink 修饰的笔记文本变量,每一次改动,都会实时存入本地存储,无惧意外关闭应用导致数据丢失。
- 协同:与本地存储模块紧密协作,像是和鸿蒙系统的文件系统 API 配合,一方面接收存储数据初始化组件状态,另一方面,持续推送状态更新,让存储系统与应用内状态互为表里,协同维护数据的完整性与即时性。
-
@StorageProp
- 功能:和 @Prop 有相似之处,不过它额外承担了存储功能。父组件传递给子组件的数据通过 @StorageProp 修饰后,子组件对该数据的修改,除了反馈给父组件更新状态,还会自动存储下来。这在配置类信息传递场景很实用,比如一个主题切换设置,从父组件传到子组件,子组件调整后存好,下次启动应用依然生效。
- 协同:整合父子组件交互流程与存储流程,让跨组件的数据流通环节和持久化环节无缝对接,降低开发者额外编写存储逻辑的负担,促使组件交互与数据留存高效协同。
- @Watcher
- 功能:
- 当一个变量或者对象属性被标注为
@Watcher
,它就进入了被 “监控” 状态。只要该变量或属性的值有所变动,与之绑定的 UI 组件会立刻感知到这些变化,从而触发对应的 UI 更新流程。这一机制让开发者能够轻松构建响应式的用户界面,把数据的动态更新与 UI 的实时刷新紧密关联起来。例如,在一个实时显示股票价格的鸿蒙应用中,代表股价的变量添加上@Watcher
,股价数据从后台推送过来发生改变时,对应的股价展示 UI 组件,像是文本标签、走势图,会马上更新显示最新价格。
- 当一个变量或者对象属性被标注为
- 协同:
- 和数据获取逻辑协同:常与网络请求、本地数据读取等数据获取手段配合。后端源源不断推送新数据,或是本地数据库数据更新,被
@Watcher
标记的数据接收新值,随即驱动 UI 协同更新,保障展示内容与最新数据同步。 - 与组件生命周期协同:在组件的生命周期各个阶段,
@Watcher
持续发挥作用。从组件创建之初初始化数据,到后续运行中数据的多次更迭,无论组件处于活跃、暂停状态,只要数据改变,就能精准更新 UI,维持组件状态与 UI 展示在全生命周期内的一致性。 - 跟其他状态管理机制协同:与
@State
、@Prop
等装饰器共存时,进一步细化状态管控。@State
侧重于本地组件状态,@Prop
管理父子组件间数据传递,@Watcher
则专注于数据变化触发 UI 更新这一关键环节,它们相互交织,为复杂应用的精准状态管理筑牢根基。
- 和数据获取逻辑协同:常与网络请求、本地数据读取等数据获取手段配合。后端源源不断推送新数据,或是本地数据库数据更新,被
@Observed装饰器和@ObjectLink装饰器使用场景?
@Observed 和 @ObjectLink 是 HarmonyOS 开发中用于处理嵌套对象或数组的数据同步装饰器。它们主要用于确保数据模型中的属性变化能够反映到视图上,特别是在 dealing with nested objects or arrays。
@Observed 装饰器 @Observed 用于修饰类,它允许观察类的属性变化。这使得开发者可以在类的属性被修改时得到通知,从而执行相应的操作,如更新UI。以下是使用 @Observed 的一个示例:
@Observed
class Person {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}
}
在这个例子中,Person
类的 name
和 age
属性将被观察。当这些属性发生变化时,由于 Person
类被 @Observed
装饰,所以这些变化会被自动同步到使用 Person
实例的组件中。
@ObjectLink 装饰器 @ObjectLink 用于在父组件和子组件之间建立双向数据绑定。它通常与 @Observed 联合使用,以便将 @Observed 装饰的类的实例传递给子组件,并确保任何对类实例的修改都能反映到父组件和子组件的UI中。以下是使用 @ObjectLink 的一个示例:
@Component
struct MyPerson {@ObjectLink person: Personbuild() {Column() {Text(`姓名: $${this.person.name}`).fontSize(20).fontWeight(FontWeight.Bold)Text(`年龄: $${this.person.age}`).fontSize(15).fontWeight(FontWeight.Regular)}}
}
在这个例子中,MyPerson
组件通过 @ObjectLink
接收一个 Person
实例。这样,任何对 Person
实例属性的修改都会导致UI的更新。
通过这种方式,@Observed 和 @ObjectLink 帮助开发者管理和同步复杂的数据结构,简化代码
鸿蒙关系型数据库是哪个?使用场景是什么?
鸿蒙操作系统中的关系型数据库是指基于SQLite组件实现的数据库管理系统。这种数据库管理系统提供了一套完整的本地数据库管理机制,支持传统的增、删、改、查等操作,并且能够执行用户自定义的SQL语句,以应对更复杂的场景需求。
主要功能和参数:
- RdbStore :这是操作关系型数据库的核心接口,通过这个接口可以执行各种数据库操作1。它需要三个参数:
context
(应用上下文)、config
(数据库配置)和callback
(回调函数)。 - ResultSet :这是数据库查询结果的集合,允许用户遍历和访问查询结果。
- RdbPredicates :用于定义数据库操作的条件1。
使用场景:
- 复杂关系数据存储 :适用于需要存储具有复杂关系的数据场景,如学校的学生成绩或公司的员工信息2。这些数据不仅包括基本的信息(如姓名、编号),还可能涉及多种多样的关联信息(如课程成绩、部门职位等)。
- 数据持久化 :关系型数据库提供了强大的数据持久化能力,能够确保数据的完整性和一致性,特别适合需要高频更新和复杂查询的应用。
注意事项:
- 在使用过程中,建议单条数据不要超过2MB,以确保数据的正确读取。
- 大数据量查询时,应尽量避免一次性查询过多数据,建议不超过5000条,并在
TaskPool
中执行此类操作,以减少对应用性能的影响。
数据库增删改查的API?
鸿蒙操作系统为SQLite数据库的增删改查操作提供了以下API:
-
RdbStore接口 :- 获取RdbStore :
getRdbStore(context: Context, config: StoreConfig, version: number, callback: AsyncCallback<RdbStore>): void
12- 参数 :
context
:应用的上下文。config
:与此RDB存储相关的数据库配置12。version
:数据库版本。callback
:指定callback回调函数,返回RdbStore对象12。
- 说明 :通过这个接口,开发者可以获得一个RdbStore对象,进而执行数据库的操作。这个接口从API版本7开始支持,但已从API版本9起不再维护,推荐使用新的
relationalStore
模块1。
- 参数 :
- 获取RdbStore :
-
relationalStore模块 :
- 获取RdbStore :
getRdbStore(context: Context, config: StoreConfig, callback: AsyncCallback<RdbStore>): void
2- 参数 :
context
:应用的上下文。config
:与此RDB存储相关的数据库配置。callback
:指定callback回调函数,返回RdbStore对象。
- 说明 :这是推荐使用的 newer API,从API版本9开始支持。它允许开发者配置数据库操作的参数,并通过回调获取操作结果。
- 参数 :
- 获取RdbStore :
relationalStore 的增删改查属性
insertSync
- insertSync(table: string, values: ValuesBucket, conflict?: ConflictResolution):number
- 向目标表中插入一行数据。由于共享内存大小限制为2Mb,因此单条数据的大小需小于2Mb,否则会查询失败。
batchInsertSync
- batchInsertSync(table: string, values: Array<ValuesBucket>):number
- 向目标表中插入一组数据。
updateSync
- updateSync(values: ValuesBucket, predicates: RdbPredicates, conflict?: ConflictResolution):number
- 根据RdbPredicates的指定实例对象更新数据库中的数据。由于共享内存大小限制为2Mb,因此单条数据的大小需小于2Mb,否则会查询失败。
deleteSync
- deleteSync(predicates: RdbPredicates):number
- 根据RdbPredicates的指定实例对象从数据库中删除数据。
querySync
- querySync(predicates: RdbPredicates, columns?: Array<string>):ResultSet
- 根据指定条件查询数据库中的数据。对query同步接口获得的resultSet进行操作时,若逻辑复杂且循环次数过多,可能造成freeze问题,建议将此步骤放到taskpool线程中执行。
鸿蒙数据库支持事务吗?事务是用来解决什么问题的?
鸿蒙的数据库支持事务。
事务主要用于解决数据库操作中的一系列复杂问题,确保数据的完整性、可靠性与一致性,具体如下:
- 原子性问题
- 场景:设想一个在线购票系统,当用户购买一张演出票时,数据库需要执行多个操作,比如减少对应场次的余票数量、将购票记录插入订单表、更新用户消费积分等。要是没有事务机制,在执行部分操作后系统突然崩溃,例如插入订单表成功了,但余票数量没更新,就会造成数据状态混乱。
- 解决:事务具备原子性,将这一系列购票相关操作囊括其中,它们被当作一个不可拆分的单元。要么所有操作都顺利完成,要么只要其中一个环节出错,整个事务就会回滚,数据库状态恢复到事务开启前,避免出现 “半吊子” 数据。
- 一致性问题
- 场景:在银行转账业务里,从账户 A 转出一笔钱,必须等额转入账户 B,两边的账户余额总和要始终保持不变。若转账中途遭遇网络故障,只扣了 A 账户的钱,没能成功汇入 B 账户,就打破了账户余额的一致性。
- 解决:事务把转账涉及的扣钱、转账操作绑定在一起,成功执行完所有步骤,才能提交事务,让数据库状态更新;要是过程中出现意外,事务回滚,维持账户数据的一致性。
- 隔离性问题
- 场景:多用户并发访问数据库的电商库存管理场景下,多个管理员同时处理商品入库、出库事宜。如果没有隔离机制,两个管理员同时读取某热门商品的库存数,又各自基于读取到的数据去更新库存,就容易导致库存数据错误,后续订单分配也会混乱。
- 解决:事务设定不同的隔离级别,通过隔离并发事务,让每个事务执行时不受其他事务干扰。在高隔离级别下,当一个事务正在操作库存数据时,其他事务必须等待它完成,避免并发冲突,保证每个操作都基于准确的库存数据。
- 持久性问题
- 场景:对于关键业务数据录入,如医院病历系统,医生录入患者新的诊断信息,这些数据必须永久保存。要是录入后不久发生系统崩溃,数据丢失,后续治疗就失去依据。
- 解决:事务一旦成功提交,其对数据库所做的修改就具有持久性,即使后续遭遇系统故障、重启,数据也不会丢失,因为数据库系统会运用日志、备份等机制保障已提交事务的数据安全落地。
navigation和router用过吗?哪个用的多一点?
Navigation和Router都是HarmonyOS中用于实现页面路由的机制,但它们在使用方式和提供的功能上有明显的差异。
Navigation作为一种新的路由解决方案,旨在提供更强大和灵活的功能。它允许开发者通过组件来构建页面,支持共享元素的转场,且没有路由数量限制。Navigation还支持嵌套在模态对话框中,提供更高的自定义性,如动效和属性设置。此外,Navigation在性能上也优于Router,因为它通过引用传递参数,支持动态加载组件。
Router则是一个较早的页面路由解决方案,虽然仍然使用广泛,但它的功能较为有限。Router支持通过URL地址进行页面跳转,但每个应用的页面栈容量限制为32个页面。Router也不支持一些高级功能,如共享元素动画和模态框中的路由嵌套。
根据这些信息,可以看出Navigation因为在功能性和性能上的优势,可能会被更多地用于新的HarmonyOS应用开发中。然而,Router由于其简洁性和与现有应用的兼容性,可能仍会在一些旧的应用或特定场景下使用。
总之,选择哪个工具取决于具体的应用需求和开发者的偏好。建议在新的项目中优先考虑使用Navigation,以利用其更多的功能和更好的性能。
navigation常用的生命周期?
其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期。其中,aboutToAppear和aboutToDisappear是自定义组件的生命周期(NavDestination外层包含的自定义组件),OnAppear和OnDisappear是组件的通用生命周期。剩下的六个生命周期为NavDestination独有。
- aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
- onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行。
- onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。
- onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。
- onShown:NavDestination组件布局显示之后执行,此时页面已完成布局。
- onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。
- onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。
- onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。
- onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。
- aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。
想获取navigation那个页面的栈,需要在哪个生命周期获取(用于页面跳转的哪个对象)?
在HarmonyOS开发中,获取页面栈是通过NavPathStack
对象实现的,这个对象是管理页面栈的核心。您可以通过以下方式获取页面栈的大小:
let size: number = this.pathStack.size();
这里的pathStack
是一个NavPathStack
的实例,它包含了所有页面的路径信息。您可以在需要进行页面跳转或在页面加载时获取这个信息,以便于管理页面的状态和跳转。
此外,您可以通过NavPathStack
对象进行页面的push、pop和其他操作,这些操作都会影响到页面栈的状态。因此,建议在页面的aboutToAppear
或build
方法中获取页面栈的信息,这两个方法分别在页面即将显示和页面构建时被调用,是获取页面栈的理想时机。
navigation怎么带参数跳转,跳转页怎接收参数?
在鸿蒙(HarmonyOS)开发中,通过Navigation组件传递参数通常涉及到两个方面:设置跳转参数和在目标页面中接收这些参数。以下是具体的实现步骤:
-
设置跳转参数 : 在跳转到另一个页面时,你可以通过
NavPathStack
来传递参数。例如,如果你从一个名为LoginPage
的页面跳转到UserProfilePage
,可以在pushPath
方法中设置参数,如下所示:function pushPath(name, param, animated, onPop) {has.navPathStack.pushPath({name: name,param: param,animated: animated,onPop: onPop,callback: (err, res) => commonCallback('pushPath', err, res)}); }
在这个例子中,
name
是要跳转到的页面名称,param
是要传递的参数。 -
在目标页面中接收参数 : 当你在目标页面中需要使用这些参数时,可以通过适当的方法来接收它们。这通常在目标页面的加载或初始化过程中完成,例如在
UserProfilePage
中,你可能会这样使用参数:function handleParams(params) {// 处理接收到的参数console.log("接收到的参数:", params); }
通过上述步骤,你可以在Navigation组件中有效地传递和接收参数,从而实现更复杂的功能和页面交互。
获取参数的方法
-
通过索引获取参数 :你可以使用
getParamByIndex(index)
方法来获取指定索引的NavDestination
页面的参数信息。例如,如果你想要获取索引为1的页面参数,可以使用以下代码:let param = this.pathStack.getParamByIndex(1);
-
通过页面名获取参数 :如果你知道页面的名字,可以使用
getParamByName(name)
方法来获取所有名为name
的NavDestination
页面的参数信息1。例如,如果页面名为PageOne
,你可以这样获取它的参数:let params = this.pathStack.getParamByName("PageOne");
这些方法允许你在导航过程中灵活地获取和管理页面参数,从而实现复杂的功能组合和页面间的数据交互。
通过这些方法,你可以轻松地在页面之间传递和接收参数,这对于维护页面的状态和实现复杂的导航逻辑非常有用。
git场景题:假如我在一个分支上功能写了一半,现在我需要去另一个分支写其他功能,请问用哪个git命令可以解决这个问题
- 暂存当前工作进度
- 执行
git stash
,该命令会把当前工作区(包括未提交的修改、暂存区新增内容等 )的所有改动收集起来,保存到一个类似栈的结构中,让工作目录立刻变得干净,仿佛从未做过这些修改一样。示例:
- 执行
git stash
- 切换分支
- 完成暂存后,就可以安心使用
git checkout
命令切换到目标分支,着手开发新功能。假设要切换到名为new-branch
的分支,命令如下:
- 完成暂存后,就可以安心使用
git checkout new-branch
- 恢复暂存的工作
- 当在新分支的工作告一段落,想要回到之前未完成的功能分支接着开发时,先切回原来的分支:
git checkout original-branch
- 接着,使用
git stash apply
把之前暂存的工作内容重新应用到当前工作区,让之前未完成的工作状态得以恢复,继续接着之前的进度开发:
git stash apply
需要注意的是,git stash apply
执行后,暂存的内容并不会从栈里删除。要是想删除这个已经应用的暂存项,可以额外执行 git stash drop
;要是想一步到位,在应用的同时删除暂存内容,就用 git stash pop
命令。
http和https的区别,https为啥是安全的?
HTTP(超文本传输协议)和 HTTPS(超文本传输安全协议)主要有以下几方面区别:
- 数据传输安全性
- HTTP:使用明文传输数据,数据在网络传输过程中,是以原始的文本格式呈现,这就导致像用户名、密码、银行卡号这类敏感信息,非常容易被网络中的第三方截获,毫无保密性可言。
- HTTPS:在传输层与应用层之间加入了 SSL/TLS 加密层,所有传输的数据都会先进行加密处理变成密文,接收方再用对应的密钥解密还原,就算数据中途被截取,第三方没有密钥也无法解读内容。
- 端口使用
- HTTP:默认工作在 80 端口,当我们在浏览器地址栏输入网址,不特别指定端口号时,浏览器就默认通过 80 端口去连接目标服务器,发起 HTTP 请求。
- HTTPS:常用的工作端口是 443,同理,访问 HTTPS 网站,若不额外输入端口号,浏览器自动从 443 端口尝试建立连接。
- 性能开销
- HTTP:因为无需加密、解密操作,传输过程相对简洁快速,对服务器的计算资源占用较少,数据传输效率更高。
- HTTPS:加密和解密过程会消耗大量的服务器 CPU、内存资源,尤其是在高并发场景下,额外的运算负担会让响应时间有所延长,性能开销明显更大。
- 证书要求
- HTTP:不强制要求使用数字证书,网站搭建部署更为简便直接,小型个人站点常采用 HTTP 协议。
- HTTPS:必须申请权威 CA 机构颁发的 SSL/TLS 数字证书,以此证明服务器身份合法性,证书申请、更新等流程增加了网站运维成本与复杂度。
HTTPS 之所以安全,核心在于它的加密机制与身份认证体系:
- 加密机制
- 混合加密:结合了对称加密与非对称加密的优势。通信开始时,客户端与服务器利用非对称加密(公钥、私钥体系 )来安全交换对称加密所需的密钥 ,后续大量的数据传输就采用运算速度更快的对称加密。例如,客户端向服务器发起请求,服务器把公钥发给客户端,客户端利用公钥加密自己生成的对称密钥,再传回给服务器,之后双方就用这个对称密钥加密传输实际数据,兼顾了安全性与传输效率。
- 身份认证
- 数字证书:服务器部署 SSL/TLS 数字证书,证书里包含服务器的公钥以及服务器的身份信息,诸如域名、组织等。客户端访问服务器时,会验证证书真伪,只有通过 CA 机构严格审核验证的合法证书,客户端才会信任该服务器与之通信,杜绝中间人伪装成合法服务器窃取数据的隐患,防止遭遇钓鱼网站。
https是怎么加密的?
非对称加密与证书验证
- 服务器发送证书:客户端向服务器发起 HTTPS 连接请求后,服务器会将包含自身公钥、域名、证书颁发机构、证书有效期等信息的数字证书发送给客户端。
- 客户端验证证书:客户端接收到证书后,会验证证书的合法性,包括检查证书是否由可信的证书机构颁发、证书是否在有效期内、证书中的域名与服务器的实际域名是否一致等。如果证书验证不通过,客户端会中断连接;如果验证通过,则进入下一步。
对称加密密钥协商
- 客户端生成对称密钥:客户端在本地生成一个随机数,用作对称加密的密钥。
- 客户端加密并发送密钥:客户端取出证书中的公钥,用该公钥对随机数进行加密,将加密后的结果发送到服务端。
- 服务端解密获取密钥:服务端收到客户端发来的加密后的密钥,先用自己的私钥解密,得到对称密钥。
数据加密传输
- 使用对称密钥加密数据:客户端和服务器使用协商好的对称密钥对传输的数据进行加密和解密。在数据传输过程中,发送方将数据用对称密钥加密成密文后发送,接收方收到密文后用相同的对称密钥进行解密还原出原始数据。
信息仅供参考,如有更优方案,欢迎评论,谢谢
相关文章:
鸿蒙面试 2025-01-10
写了鉴权工具,你在项目中申请了那些权限?(常用权限) 位置权限 : ohos.permission.LOCATION_IN_BACKGROUND:允许应用在后台访问位置信息。 ohos.permission.LOCATION:允许应用访问精确的位置信息…...
在vscode上
第一步 安装插件 (1)从菜单处打开vscode,之后点击左侧“拓展”,在搜索栏输入“platform”,安装这个插件。 注:安装过程可能会慢一点,可以尝试连接自己的热点 (2)安装完…...
用WebGPU实现现代Web3D渲染——突破传统性能瓶颈的解决方案
引言 随着Web技术的不断发展,Web3D应用的需求不断增加。从游戏引擎到可视化工具,3D渲染技术正在被广泛地应用。然而,传统WebGL技术在性能、效率和灵活性上仍存在局限性。而WebGPU作为一种新兴的Web标准,为现代3D渲染提供了强大而…...
HTML5 加载动画(Loading Animation)
加载动画(Loading Animation)详解 概述 加载动画是指在数据加载过程中,向用户展示的一种视觉效果,旨在提升用户体验,告知用户系统正在处理请求。它可以减少用户的等待焦虑感,提高界面的互动性。 常见的加…...
.NET AI 开发人员库 --AI Dev Gallery简单示例--问答机器人
资源及介绍接上篇 nuget引用以下组件 效果展示: 内存和cpu占有: 代码如下:路径换成自己的模型路径 模型请从上篇文尾下载 internal class Program{private static CancellationTokenSource? cts;private static IChatClient? model;privat…...
Linux 高级路由 —— 筑梦之路
Linux 高级路由详解 本文将基于您提供的 Linux 高级路由极简教程 文章,深入探讨 Linux 高级路由的概念、配置方法以及应用场景。 一、什么是 Linux 高级路由? Linux 高级路由是指利用 Linux 内核提供的强大网络功能,实现超越传统路由表和默…...
实习总结(经历篇)
自从读研后,有可能是看见同龄的财会专业的同学去各种大厂实习:B站,阿里等,身边也有舍友在有过小厂实习,所以一直有个想法就是去实习,这个想法终于在研一的暑假快开始前被我赋予行动。 研一暑假和同门一起在boss等招聘软件投简历,但是当时并没有很好的对简历做修改,投递…...
【ShuQiHere】pandas 与 DataFrame 全面详解
【ShuQiHere】 本文将为您系统介绍 pandas 与 DataFrame 之间的区别,着重讲解 DataFrame 的常用方法以及相关的数据可视化操作,包括 df.hist()、df.plot()、df.boxplot() 等。无论您是数据分析新手还是有经验的专业人士,都可以从本文中快速掌…...
【回眸】发财日记
积累本金,有舍有得。 上学时在线上兼职,基本够开销没攒下钱,上班之后工资还能攒下不少。 对于花销要有舍有得。认同一句话“买东西要买能力范围内最好的”。 所以,每次花钱前都会思考: 是否需要,是否能替代已有产品&…...
文件读写到SQLite数据库的方法
在 SQLite 数据库中,将文件读写到数据库的常见方法主要有以下几种: 1. 将文件以 BLOB 类型存储 BLOB(Binary Large Object) 是 SQLite 中的二进制数据类型,可以直接用来存储文件内容。 步骤: 创建表 创建一…...
基于SDN的ddos攻击检测与防御
本项目依赖mininet, floodlight, sFlow-RT 1,启动floodlight cd floodlightjava -jar target/floodlight.jar 浏览器访问http://localhost:8080/ui/pages/index.html 或者http://localhost:8080/ui/index.html 2,创建 mininet拓扑 sudo mn --toposingl…...
RocketMQ 和 Kafka 有什么区别?
目录 RocketMQ 是什么? RocketMQ 和 Kafka 的区别 在架构上做减法 简化协调节点 简化分区 Kafka 的底层存储 RocketMQ 的底层存储 简化备份模型 在功能上做加法 消息过滤 支持事务 加入延时队列 加入死信队列 消息回溯 总结 来源:面试官:RocketMQ 和 Kafka 有…...
关于人工智能学习框架
人工智能学习框架:智能时代的强大引擎 在人工智能蓬勃发展的今天,学习框架如同一座座坚实的桥梁,连接着理论与实践,承载着创新与突破,为智能科技的前行提供了强大动力。本文将深入剖析人工智能学习框架的重要意义、核…...
Android14上使用libgpiod[gpioinfo gpioget gpioset ...]
环境 $ cat /etc/os-release NAME="Ubuntu" VERSION="20.04.5 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.5 LTS" VERSION_ID="20.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="…...
【文件I/O】UNIX文件基础
IO编程的本质是通过 API 操作 文件。 什么是 IO I - Input 输入O - Output 输出 这里的输入和输出都是站在应用(运行中的程序)的角度。外部特指文件。 这里的文件是泛指,并不是只表示存在存盘中的常规文件。还有设备、套接字、管道、链接…...
TensorFlow Quantum快速编程(高级篇)
五、实战:量子分类器应用 5.1 数据准备 在实战构建量子分类器时,数据准备是基石环节。选用鸢尾花数据集,这一经典数据集在机器学习领域应用广泛,其涵盖了三种鸢尾花品种的样本,每个样本包含花萼长度、花萼宽度、花瓣长度、花瓣宽度四个特征。鉴于本次构建二分类量子分类…...
无人机+无人车:车机协同技术探索详解
无人机与无人车之间的协同技术是一种重要的研究方向,它结合了无人机的高空视野和无人车的地面移动能力,旨在实现更高效、灵活的作业。以下是对无人机与无人车车机协同技术的详细探索: 一、技术基础 1. 通信机制: 无人机与无人车…...
解决WordPress出现Fatal error: Uncaught TypeError: ftp_nlist()致命问题
错误背景 WordPress版本:wordpress-6.6.2-zh_CN WooCommerce版本:woocommerce.9.5.1 WordPress在安装了WooCommerce插件后,安装的过程中没有问题,在安装完成后提示: 此站点遇到了致命错误,请查看您站点管理…...
scrapy爬取图片
scrapy 爬取图片 环境准备 python3.10scrapy pillowpycharm 简要介绍scrapy Scrapy 是一个开源的 Python 爬虫框架,专为爬取网页数据和进行 Web 抓取而设计。它的主要特点包括: 高效的抓取性能:Scrapy 采用了异步机制,能够高效…...
【数据库】六、数据库设计
文章目录 六、数据库设计1 数据库设计步骤1.1 规划阶段1.2 需求分析1.3 概念设计阶段(重点)1.4 逻辑设计阶段(重点)1.5 物理设计阶段1.6 数据库的实现1.7 数据库运行与维护 2 概念模型设计2.1 ER模型2.1.1 ER模型的基本元素2.1.2 联系的设计2.1.3 采用ER模型的概念设计2.1.4 ER…...
错误的类文件: *** 类文件具有错误的版本 61.0, 应为 52.0 请删除该文件或确保该文件位于正确的类路径子目录中
一、问题 用maven对一个开源项目打包时,遇到了“错误的类文件: *** 类文件具有错误的版本 61.0, 应为 52.0 请删除该文件或确保该文件位于正确的类路径子目录中。”: 二、原因 原因是当前java环境是Java 8(版本52.0),但…...
不同音频振幅dBFS计算方法
1. 振幅的基本概念 振幅是描述音频信号强度的一个重要参数。它通常表示为信号的幅度值,幅度越大,声音听起来就越响。为了更好地理解和处理音频信号,通常会将振幅转换为分贝(dB)单位。分贝是一个对数单位,能…...
《探秘开源多模态神经网络模型:AI 新时代的万能钥匙》
《探秘开源多模态神经网络模型:AI 新时代的万能钥匙》 一、多模态模型的崛起之路(一)从单一到多元:模态的融合演进(二)关键技术突破:解锁多模态潜能 二、开源多模态模型深度剖析(一&…...
计算机网络之---端口与套接字
总括 端口:是计算机上用于标识网络服务的数字标识符,用于区分不同的服务或应用程序。套接字:是操作系统提供的用于进程间网络通信的编程接口,允许程序通过它来进行数据的发送、接收和连接管理。关系:端口号用于标识服…...
el-tabs中tabs过多造成form表单输入的时候卡顿
这里写自定义目录标题 tabs过多造成的输入卡顿解决方案方案一方案二 出现的并发问题解决方案 tabs过多造成的输入卡顿 描述:前端要写一个需求,大概有一百多个tab渲染过来,每个tab中都是一个表单,这个时候数据渲染任务加重&#x…...
vue+vite打包空白问题
在使用vuevite创建项目之后如果我们在部署项目的时候使用的不是主域名 比如www.custom.com 而是使用了www.custom.com/test 为访问域名的时候 如果不小心没有注意到这个变化 在打包上线之后会出现页面空白 js或者css404问题 我们可以在vite.config.ts去配置路径base export de…...
【python翻译软件V1.0】
如果不想使用密钥的形式,且需要一个直接可用的中英文翻译功能,可以使用一些免费的公共 API,如 opencc 或其他无需密钥的库,或直接用 requests 获取翻译结果。 其中,我可以给你一个简单的代码示例,使用 tra…...
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(while循环应用)
实战训练1—求最大公约数 问题描述: 给定两个正整数,求它们的最大公约数。 输入格式: 输入一行,包含两个正整数。 输出格式: 输出一行,包含gcd正整数,即这两个正整数的最大公约数。 输入…...
HTTPS协议的基础与工作原理
什么是HTTPS? HTTPS(HyperText Transfer Protocol Secure)是HTTP协议的安全版本,它通过SSL/TLS协议对通信数据进行加密,确保数据的安全传输。与HTTP相比,HTTPS能防止数据被窃取、篡改或伪造,广…...
手游业务该如何选择服务器?
在网络游戏行业当中,对于服务器配置的需求是非常高的,大型的网络游戏需要服务器的高稳定性,来保证用户的游戏体验感,那么对于手游业务来说该如何进行选择服务器呢? 手游业务通常都需要处理大量的用户数据信息和并发请求…...
Python 数据建模完整流程指南
在数据科学和机器学习中,建模是一个至关重要的过程。通过有效的数据建模,我们能够从原始数据中提取有用的洞察,并为预测或分类任务提供支持。在本篇博客中,我们将通过 Python 展示数据建模的完整流程,包括数据准备、建…...
java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
今天在朋友机子上运行代码,在生成token的时候,遇到了这样一个问题: Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter at io.jsonwebtoken.impl.Base64Codec.decode(Base64Codec.java:26) ~[jjwt-0.9.1.jar:0.…...
12. C语言 数组与指针(深入理解)
本章目录: 前言1. 什么是数组?2. 数组的声明与初始化声明数组初始化数组 3. 访问数组元素遍历数组 4. 获取数组长度使用 sizeof 获取长度使用宏定义简化 5. 数组与指针数组名与指针的区别使用指针操作数组 6. 多维数组遍历多维数组 7. 数组作为函数参数8. 高级技巧与…...
C#用直线和曲线抗锯齿
使用 GDI 绘制一条线时,要提供线条的起点和终点,但不必提供有关线条上各个像素的任何信息。 GDI 与显示驱动程序软件协同工作,确定将打开哪些像素以在特定显示设备上显示该线条。 效果对比 代码实现 关键代码 e.Graphics.SmoothingMode Sm…...
从SS到CSS:探索网页样式设计的奥秘
一、什么是CSS CSS,全称为层叠样式表(Cascading Style Sheets),是一种用于描述HTML(超文本标记语言)或XML(包括如SVG、MathML等各种XML方言)文档样式的样式表语言。 从结构和功能的…...
[Git] git reset --hard / git reset --soft
git reset --hard 功能:重置索引(暂存区)和工作目录到指定的提交状态。这意味着它会丢弃所有未提交的更改和已暂存的更改。 适用场景:当你想要完全放弃当前工作目录中的所有更改并回退到某个特定提交状态时,可以使用这…...
OIDC IdentityServer4》》授权码模式+刷新令牌
认证服务 new Client {ProtocolType "oidc",ClientName "测试",ClientId "zen",//定义客户端 Id 要唯一ClientSecrets { new Secret("abc123zenabres89jijkomnlj".Sha256()) },//Client用来获取token// 混合模式AllowedGrantTyp…...
Sql 创建用户
Sql server 创建用户 Sql server 创建用户SQL MI 创建用户修改其他用户密码 Sql server 创建用户 在对应的数据库执行,该用户得到该库的所有权限 test.database.chinacloudapi.cn DB–01 DB–02 创建服务器登录用户 CREATE LOGIN test WITH PASSWORD zDgXI7rsafkak…...
vscode开启调试模式,结合Delve调试器调试golang项目详细步骤
1.前期准备 (1).在vs code中的扩展程序中搜索并安装Go扩展程序 (2).安装 Delve 调试器 go install github.com/go-delve/delve/cmd/dlvlatest (3).打开vs code的命令面板,输入Go: Install/Update Tools,并单击该命令执行,安装或更新Go语…...
搭建Hadoop分布式集群
软件和操作系统版本 Hadoop框架是采用Java语言编写,需要java环境(jvm) JDK版本:JDK8版本 ,本次使用的是 Java: jdk-8u431-linux-x64.tar.gz Hadoop: hadoop-3.3.6.tar.gz 三台Linux虚拟节点: CentOS-7-x86_64-DVD-2…...
网络安全应急响应技术原理与应用
网络安全应急响应概述 “居安思危,思则有备,有备无患。”网络安全应急响应是针对潜在发生的网络安全事件而采取的网络安全措施。本节主要阐述网络安全响应的概念、网络安全应急响应的发展、网络安全应急响应的相关要求。 17.1.1 网络安全应急响应概念 网…...
01 Oracle自学环境搭建
1 Oracle12C安装 1.1 下载 官网地址:https://www.oracle.com/ 解压安装包 运行安装程序 1.2 安装 配置安全更新 软件更新 安装选项 系统类 Oracle主目录用户选择 使用现有windows用户:如果选择该项,则需要指定没有管理权限的用户。 创建新Wi…...
MYSQL----------MySQL权限管理
1 MySQL权限管理 .1.1 权限系统的工作原理 查看用户权限 -- 查看用户的权限 SHOW GRANTS FOR usernamelocalhost;解释:这条SQL语句用于查看指定用户在本地主机上的权限。其中username是要查看权限的用户。 .1.2 权限表的存取 查询权限表(以user表为例&a…...
学习HLS.js
前言 HTTP 实时流(也称为HLS(.m3u8))是一种基于HTTP的自适应比特率流通信协议。HLS.js依靠HTML5视频和MediaSource Extensions进行播放,其特点:视频点播和直播播放列表、碎片化的 MP4 容器、加密媒体扩展 …...
Zustand selector 发生 infinate loops的原因以及解决
Zustand selector 发生 infinate loops 做zustand tutorial project的时候,使用选择器方法引入store,出现Maximum update depth exceeded,也就是组件一直重新渲染,改成直接使用store就没有不会出现这个问题。如下: // const [xIs…...
Unity自定义编辑器:基于枚举类型动态显示属性
1.参考链接 2.应用 target并设置多选编辑 添加[CanEditMultipleObjects] using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor;[CustomEditor(typeof(LightsState))] [CanEditMultipleObjects] public class TestInspector :…...
donet (MVC)webAPI 的接受json 的操作
直接用对象来进行接收,这个方法还不错的。 public class BangdingWeiguiJiluController : ApiController{/// <summary>/// Json数据录入错误信息/// </summary>/// <param name"WeiguiInfos"></param>/// <returns></r…...
GitHub 新手入门指南
一、GitHub 简介 GitHub 是全球最大的代码托管平台,它基于 Git 版本控制系统,为开发者提供了一个集中存储、管理和协作开发代码的空间。在这里,你可以找到无数开源项目,也可以将自己的项目与全球开发者社区共享,促进知…...
Django后端相应类设计
通用的ApiResponse类:用于生成统一的 API 响应格式。每个响应都包含以下字段(每个接口最终的返回数据格式): status_code:HTTP 状态码(如 200、400、500 等)message:响应的描述信息…...
完美解决VMware 17.0 Pro安装ubuntu、Deepin等虚拟机后卡顿、卡死问题
这两天在 VM 17 Pro 中安装了ubuntu 24.1 和Deepin 23.9 等Linux操作系统,在使用过程中出现过数次卡顿、卡死问题,现记录整理解决方法如下: 一、问题描述 安装虚拟机时、以及安装完成后正常使用时出现鼠标点击卡顿、系统反应慢、卡死等问题…...