HarmonyOS开发实例:【菜单app】

 简介

分布式菜单demo 模拟的是多人聚餐点菜的场景,不需要扫码关注公众号等一系列操作,通过分布式数据库可以方便每个人可及时查看到订单详情,数量,总额等;效果如下

  • demo效果

    show

工程目录

完整的项目结构目录如下

├─entry
│  └─src
│      └─main
│          │  config.json  // 应用配置文件
│          │  
│          ├─ets
│          │  └─MainAbility
│          │      │  app.ets  // 应用程序主入口
│          │      │  
│          │      ├─model
│          │      │      CommonLog.ets  // 日志类
│          │      │      MenuData.ets  // 初始化菜单数据类
│          │      │      MenuListDistributedData.ets  // 加入菜单分布式数据库
│          │      │      RemoteDeviceManager.ets  // 分布式拉起设备管理类
│          │      │      SubmitData.ets   // 结算订单分布式数据库
│          │      │      
│          │      └─pages
│          │              detailedPage.ets // 菜品详细页面
│          │              index.ets // 首页
│          │              menuAccount.ets // 订单详情页面
│          │              
│          └─resources
│              ├─base
│              │  ├─element
│              │  │      string.json
│              │  │      
│              │  ├─graphic
│              │  ├─layout
│              │  ├─media   // 存放媒体资源
│              │  │      icon.png
│              │  │      icon_add.png
│              │  │      icon_back.png
│              │  │      icon_cart.png
│              │  │      
│              │  └─profile
│              └─rawfile

鸿蒙开发文档qr23.cn/AKFP8k参考(点击或者复制前往)。

开发步骤

搜狗高速浏览器截图20240326151450.png

1. 新建OpenHarmony ETS项目

在DevEco Studio中点击File -> New Project ->Empty Ability->Next,Language 选择ETS语言,最后点击Finish即创建成功。 

image-20211124092813545

image-20211124092813545

2. 编写商品展示主页面

image-20211124093106260

2.1用户信息

1): 主要用到[Flex]容器[Image]和[Text]组件;

2): 用户名称和头像图标,根据设备序列号不同,可展示不同的名称和图标;

3): 点击右上角分享的小图标,可分布式拉起局域网内的另一台设备;

@Component
struct MemberInfo {@Consume userImg: Resource@Consume userName: stringaboutToAppear() {// 根据设备序列号不同,展示不同的名称和图标CommonLog.info('==serial===' + deviceInfo.serial);if (deviceInfo.serial == '150100384754463452061bba4c3d670b') {this.userImg = $r("app.media.icon_user")this.userName = 'Sunny'}else {this.userImg = $r("app.media.icon_user_another")this.userName = 'Jenny'}}build() {Flex({ direction: FlexDirection.Column }) {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Image(this.userImg).width('96lpx').height('96lpx').margin({ right: '18lpx' })Text(this.userName).fontSize('36lpx').fontWeight(FontWeight.Bold).flexGrow(1)Image($r("app.media.icon_share")).width('64lpx').height('64lpx')}// 打开分布式设备列表.onClick(() => {this.DeviceDialog.open()}).layoutWeight(1).padding({ left: '48lpx', right: '48lpx' })Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Column() {Text('124').fontSize('40lpx').margin({ bottom: '24lpx' })Text('积分').fontSize('22lpx').opacity(0.4)}.flexGrow(1)Column() {Text('0').fontSize('40lpx').margin({ bottom: '24lpx' })Text('优惠劵').fontSize('22lpx').opacity(0.4)}.flexGrow(1)Column() {Image($r("app.media.icon_member")).width('48lpx').height('48lpx').margin({ bottom: '24lpx' })Text('会员码').fontSize('22lpx').fontColor('#000000').opacity(0.4)}.flexGrow(1)}.layoutWeight(1)}.width('93%').height('25%').borderRadius('16lpx').backgroundColor('#FFFFFF').margin({ top: '24lpx', bottom: '32lpx' })}
}
2.2列表展示

1): 主要用到[Flex]容器 和[Scroll]容器[Image]和[Text]组件;

2): 从首页点击列表进入菜品详细页面,点菜成功后会自动返回首页,此时列表需要动态更新菜品的数量;

@Component
struct MenuHome {private specialty: any[]private winterNew: any[]private classic: any[]private soup: any[]private menuItems: MenuData[]private titleList = ['招牌菜', '冬季新品', '下饭菜', '汤品']@State name: string = '招牌菜'build() {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start }) {Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceAround }) {ForEach(this.titleList, item => {Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {Text(item).fontSize('24lpx')}.padding({ left: '24lpx' }).backgroundColor(this.name == item ? '#1A006A3A' : '#FFFFFF').height('160lpx').onClick(() => {this.name = itemif (this.name == '招牌菜') {this.menuItems = initializeOnStartup(this.specialty);}else if (this.name == '冬季新品') {this.menuItems = initializeOnStartup(this.winterNew);}else if (this.name == '下饭菜') {this.menuItems = initializeOnStartup(this.classic);}else if (this.name == '汤品') {this.menuItems = initializeOnStartup(this.soup);}})}, item => item)}.width('20%').backgroundColor('#FFFFFF')Flex({ direction: FlexDirection.Column }) {Text(this.name).fontSize('32lpx').fontWeight(FontWeight.Bold).opacity(0.4).height('8%')Scroll() {Column() {List() {ForEach(this.menuItems, item => {ListItem() {MenuListItem({ menuItem: item })}}, item => item.id.toString())}}}.height('92%')}.margin({ left: '10lpx' }).width('75%')}.height('50%')}
}
2.3底部总额

1): 主要用到[Flex]容器 和[Stack]容器[Image]和[Text]组件;

2): 从首页点击列表进入菜品详细页面,点菜成功后会自动返回首页,更新订单数量和总额;

3): 点击底部总额框,将订单列表加入分布式数据库,@entry模拟监听数据库变化,拉起订单列表详情页面;

@Component
struct TotalInfo {@Consume TotalMenu: any[];private total: number = 0;private amount: number = 0;private remoteData: MenuListDataaboutToAppear() {for (var index = 0; index < this.TotalMenu.length; index++) {this.total = this.total + this.TotalMenu[index].price * this.TotalMenu[index].quantitythis.amount = this.amount + this.TotalMenu[index].quantity}}build() {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Stack({ alignContent: Alignment.Center }) {Image($r("app.media.icon_cart")).width('96lpx').height('96lpx').margin({ left: '22lpx' })Text(this.amount.toString()).backgroundColor('#F84747').borderRadius('30plx').fontSize('24plx').textAlign(TextAlign.Center).fontColor('#FFFFFF').width('50lpx').height('50lpx').margin({ left: '100lpx', bottom: '85lpx' })}.width('150lpx').height('150lpx')Text('¥').fontSize('22lpx').fontColor('#006A3A').margin({ left: '22lpx' })Text(this.total.toString()).fontSize('40lpx').fontColor('#006A3A').flexGrow(1)Text('点好了').height('100%').width('35%').fontColor('#FFFFFF').backgroundColor('#F84747').textAlign(TextAlign.Center)}// 将总的订单数据,加入分布式数据库.onClick(() => {this.remoteData.putData("menu_list", this.TotalMenu)}).width('100%').height('10%').backgroundColor('#FFFFFF')}
}
3. 编写菜单详细页面

image-20211124093106260

3.1 菜单详情

1): 主要用到[Flex]容器 [Image]和[Text]组件[Button]组件;

2): 辣度可以选择;

3):点击选好了,需要判断该菜品是否已经在总订单里面,并判断是哪一个用户添加,根据判断,做出相应的增加;

@Component
struct detailInfo {private menuItemprivate spicyList = ['正常辣', '加辣', '少辣']@State spicy: string = '正常辣'private TotalMenu: any[]private index = 0private userName: stringbuild() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {Flex({ direction: FlexDirection.Row }) {Flex() {Image(this.menuItem.imgSrc).objectFit(ImageFit.Contain)}Flex({ direction: FlexDirection.Column }) {Text(this.menuItem.name).fontSize('32lpx').flexGrow(1)Text(this.menuItem.remarks).fontSize('22lpx').fontColor('#000000').opacity(0.6).flexGrow(1)Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Text('¥').fontSize('22lpx')Text(this.menuItem.price.toString()).fontSize('40lpx')Text('/份').fontSize('22lpx').flexGrow(1)Image($r("app.media.icon_reduce")).width('44lpx').height('44lpx').onClick(() => {prompt.showToast({message: "Reduce function  to be completed",duration: 5000})})Text(this.menuItem.quantity.toString()).margin({ left: '15lpx', right: '15lpx' })Image($r("app.media.icon_add")).width('44lpx').height('44lpx').margin({ right: '15lpx' }).onClick(() => {prompt.showToast({message: "Increase function to be completed",duration: 5000})})}.flexGrow(2)}}.height('40%').margin({ top: '40lpx', bottom: '24lpx' })Button().backgroundColor('#000000').opacity(0.1).height('2lpx').margin({ left: '24lpx' }).width('92%')Flex({ direction: FlexDirection.Row }) {Button().backgroundColor('#006A3A ').width('8lpx').height('48lpx').margin({ right: '12lpx' })Text('辣度')}.margin({ left: '44lpx', top: '48lpx', bottom: '32lpx' })Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceEvenly }) {ForEach(this.spicyList, item => {Button(item).fontSize('28lpx').height('60lpx').width('156lpx').borderRadius('12lpx').backgroundColor(this.spicy == item ? '#006A3A' : '#0D000000').fontColor(this.spicy == item ? '#FFFFFF' : '#000000').onClick(() => {this.spicy = item})}, item => item)}}.margin({ top: '56lpx' }).width('92%').height('50%').borderRadius('16lpx').backgroundColor('#FFFFFF')Button('选好了').fontSize('36lpx').width('80%').height('7%').backgroundColor('#F84747').onClick(() => {for (this.index = 0; this.index < this.TotalMenu.length; this.index++) {if (this.TotalMenu[this.index].name == this.menuItem.name && this.TotalMenu[this.index].spicy == this.spicy) {this.TotalMenu[this.index].quantity = this.TotalMenu[this.index].quantity + 1;if (this.userName == 'Sunny') {this.TotalMenu[this.index].userNumber = this.TotalMenu[this.index].userNumber + 1;} else if (this.userName == 'Jenny') {this.TotalMenu[this.index].anotherUserNumber = this.TotalMenu[this.index].anotherUserNumber + 1;}break;}}// 菜名不一样,辣度不一样,都需要重新push到列表里面if (this.index == this.TotalMenu.length) {this.menuItem.spicy = this.spicy;this.menuItem.quantity = 1;//根据不用的用户名称,if (this.userName == 'Sunny') {this.menuItem.userNumber = 1;} else if (this.userName == 'Jenny') {this.menuItem.anotherUserNumber = 1;}this.TotalMenu.push(this.menuItem);}router.push({uri: 'pages/index',params: { menuItem: this.menuItem, TotalMenu: this.TotalMenu }})}).margin({ top: '10%' })}}
}
4. 编写订单详情页面

image-20211124093106260

4.1 订单列表

1): 主要用到[Flex]容器[Image]和[Text]组件[Button]组件;

2): 点击下单,将"submitOk" 加入分布式数据库,监听数据库变化后,弹出自定义对话框;

@Component
struct TotalItem {private totalMenu: MenuDatabuild() {Flex({ direction: FlexDirection.Column }) {Flex({ direction: FlexDirection.Row, alignContent: FlexAlign.Start, justifyContent: FlexAlign.Start }) {Image(this.totalMenu.imgSrc).width('210lpx').height('100%')Flex({ direction: FlexDirection.Column }) {Text(this.totalMenu.name).fontSize('32lpx').flexGrow(1)Text(this.totalMenu.spicy).fontSize('22lpx').fontColor('#000000').opacity(0.6).flexGrow(1)Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Text('¥').fontSize('22lpx')Text(this.totalMenu.price.toString()).fontSize('40lpx')Text('/份').fontSize('22lpx').flexGrow(1)Text(this.totalMenu.quantity.toString()).fontColor("#F84747").fontSize('40lpx')}.flexGrow(2)}.padding({ left: '5%', top: '6%' }).width('70%')}.height('180lpx')Button().backgroundColor('#000000').opacity(0.1).height('2lpx').margin({ top: '20lpx' }).width('100%')if (this.totalMenu.userNumber > 0) {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Image(this.totalMenu.userImg).width('96lpx').height('96lpx')Text(this.totalMenu.userName).fontSize('36lpx').fontWeight(FontWeight.Bold).margin({ left: '12lpx' }).flexGrow(1)Text(this.totalMenu.userNumber.toString()).fontSize('32lpx').margin({ right: '11plx' })}.height('150lpx')}if (this.totalMenu.anotherUserNumber > 0) {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Image(this.totalMenu.anotherUserImg).width('96lpx').height('96lpx')Text(this.totalMenu.anotherUserName).fontSize('36lpx').fontWeight(FontWeight.Bold).margin({ left: '12lpx' }).flexGrow(1)Text(this.totalMenu.anotherUserNumber.toString()).fontSize('32lpx').margin({ right: '11plx' })}.height('150lpx')}}.margin({ top: '12lpx' }).borderRadius('16lpx').padding({ left: '3%', right: '3%', top: '2%' }).backgroundColor('#FFFFFF')}
}
4.2自定义弹框

1)通过**@CustomDialog**装饰器来创建自定义弹窗,使用方式可参考 [自定义弹窗];

2)规则弹窗效果如下,弹窗组成由一个[Image]和两个[Text]竖向排列组成;

所有我们可以在build()下使用[Flex]容器来包裹,组件代码如下:

@CustomDialog
struct SubmitDialog {private controller: CustomDialogControllerbuild() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {Flex({ justifyContent: FlexAlign.Center }) {Image($r("app.media.icon_success")).width('100lpx').height('80lpx')}.flexGrow(1)Text('下单成功').fontSize('36lpx').fontColor('#000000').flexGrow(1)Text('*温馨提示:菜品具体售卖情况请以店面实际情况为准哦~').fontSize('22lpx').opacity(0.6).fontColor('#000000').padding({ left: '10lpx', right: '10lpx' })}.height('300lpx').width('100%').padding({ top: '50lpx', bottom: '20lpx' })}
}

​ 3)在@entry创建CustomDialogController对象并传入弹窗所需参数,设置点击允许点击遮障层退出,通过open()方法,显示弹窗;

SubmitDialog: CustomDialogController = new CustomDialogController({builder: SubmitDialog(),autoCancel: true})
aboutToAppear() {this.remoteData.createManager(() => {let self = this;var data;if (JSON.stringify(self.remoteData.dataItem).length > 0) {data = self.remoteData.dataItem;CommonLog.info("======submit==" + data[0].submit);if (data[0].submit == "submitOk") {this.SubmitDialog.open()}}}, "com.distributed.order", "submit")}
5. 添加分布式流转

分布式流转需要在同一网络下通过 [DeviceManager组件]进行设备间发现和认证,获取到可信设备的deviceId调用 [featureAbility].startAbility ,即可把应用程序流转到另一设备。

1)创建DeviceManager实例;

2)调用实例的startDeviceDiscovery(),开始设备发现未信任设备;

3)设置设备状态监听on('deviceFound',callback),获取到未信任设备,并用discoverList变量进行维护;

4)传入未信任设备参数,调用实例authenticateDevice方法,对设备进行PIN码认证;

5)若是已信任设备,可通过实例的getTrustedDeviceListSync()方法来获取设备信息;

6)将设备信息中的deviceId传入[featureAbility].startAbility方法,实现流转;

7)流转接收方可通过[featureAbility].getWant()获取到发送方携带的数据;

项目中将上面设备管理封装至RemoteDeviceManager,通过RemoteDeviceManager的四个方法来动态维护deviceList设备信息列表,实现分布式流转只需要在deviceList中获取deviceId,然后调用featureAbility.startAbility并携带数据,即可实现分布式流转。

RemoteDeviceManager

6.分布式数据管理

[分布式数据管理]要求两个或多个设备在同一网络,才能监听到数据库的改变,从而渲染页面;开发步骤:

1)创建一个KVManager对象实例,用于管理数据库对象;

2)通过指定Options和storeId,创建并获取KVStore数据库,如下是参数说明;需要先通过createKVManager构建一个KVManager实例;

参数名类型必填说明
storeIdstring数据库唯一标识符,长度不大于[MAX_STORE_ID_LENGTH]。
options[Options]创建KVStore实例的配置信息。

3)KVStore数据库实例, KVStore.put提供增加数据的方法,如下是参数说明;

参数名类型必填说明
keystring要添加数据的key,不能为空且长度不大于[MAX_KEY_LENGTH]。
valueUint8Arraystringnumberboolean要添加数据的value,支持Uint8Array、number 、 string 、boolean,Uint8Array、string 的长度不大于[MAX_VALUE_LENGTH]。
callbackAsyncCallback回调函数。

4) KVStore数据库实例,KVStore.on订阅指定类型的数据变更通知;一般监听远端设备变化,再进行相应操作达到分布式数据共享的效果;

本项目通过storeId 值不同,创建了两个数据库,分别是MenuListDistributedData类和SubmitData类;

MenuListDistributedData是将完整订单添加到分布式数据库

@Component
struct TotalInfo {@Consume TotalMenu: any[];private total: number = 0;private amount: number = 0;private remoteData: MenuListDataaboutToAppear() {for (var index = 0; index < this.TotalMenu.length; index++) {this.total = this.total + this.TotalMenu[index].price * this.TotalMenu[index].quantitythis.amount = this.amount + this.TotalMenu[index].quantity}}build() {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Stack({ alignContent: Alignment.Center }) {Image($r("app.media.icon_cart")).width('96lpx').height('96lpx').margin({ left: '22lpx' })Text(this.amount.toString()).backgroundColor('#F84747').borderRadius('30plx').fontSize('24plx').textAlign(TextAlign.Center).fontColor('#FFFFFF').width('50lpx').height('50lpx').margin({ left: '100lpx', bottom: '85lpx' })}.width('150lpx').height('150lpx')Text('¥').fontSize('22lpx').fontColor('#006A3A').margin({ left: '22lpx' })Text(this.total.toString()).fontSize('40lpx').fontColor('#006A3A').flexGrow(1)Text('点好了').height('100%').width('35%').fontColor('#FFFFFF').backgroundColor('#F84747').textAlign(TextAlign.Center)}.onClick(() => {this.remoteData.putData("menu_list", this.TotalMenu)}).width('100%').height('10%').backgroundColor('#FFFFFF')}
}

SubmitData在订单结算是点击下单,将submitOk 添加到数据库;

@Component
struct SubmitList {private remoteData: SubmitDataprivate SubmitOK: any[] = [{submit: "submitOk"}];build() {Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Text('下单').fontSize('36lpx').fontColor('#FFFFFF')}.width('100%').height('10%').backgroundColor('#F84747').onClick(() => {this.remoteData.putData("submit", this.SubmitOK)}).margin({ top: '5%' })}
}

鸿蒙开发岗位需要掌握那些核心要领?

目前还有很多小伙伴不知道要学习哪些鸿蒙技术?不知道重点掌握哪些?为了避免学习时频繁踩坑,最终浪费大量时间的。

自己学习时必须要有一份实用的鸿蒙(Harmony NEXT)资料非常有必要。 这里我推荐,根据鸿蒙开发官网梳理与华为内部人员的分享总结出的开发文档。内容包含了:【ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战】等技术知识点。

废话就不多说了,接下来好好看下这份资料。

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。鸿蒙OpenHarmony知识←前往。下面是鸿蒙开发的学习路线图。

针对鸿蒙成长路线打造的鸿蒙学习文档。鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

其中内容包含:

《鸿蒙开发基础》鸿蒙OpenHarmony知识←前往

  1. ArkTS语言
  2. 安装DevEco Studio
  3. 运用你的第一个ArkTS应用
  4. ArkUI声明式UI开发
  5. .……

《鸿蒙开发进阶》鸿蒙OpenHarmony知识←前往

  1. Stage模型入门
  2. 网络管理
  3. 数据管理
  4. 电话服务
  5. 分布式应用开发
  6. 通知与窗口管理
  7. 多媒体技术
  8. 安全技能
  9. 任务管理
  10. WebGL
  11. 国际化开发
  12. 应用测试
  13. DFX面向未来设计
  14. 鸿蒙系统移植和裁剪定制
  15. ……

《鸿蒙开发实战》鸿蒙OpenHarmony知识←前往

  1. ArkTS实践
  2. UIAbility应用
  3. 网络案例
  4. ……

最后

鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何编译OpenHarmony自带APP

作者&#xff1a;王石 概述 OpenHarmony 的主干代码是开源社区的重要学习资源&#xff0c;对于想进行应用开发和熟悉 OpenHarmony 能力的同学主干代码是非常重要的资源&#xff0c;在主干代码的 applications 目录里聚集了很多原生的应用实现&#xff0c;那么如何编译这些代码…

广州南沙番禺联想SR530服务器主板传感器故障维修

今日分享一例广州市南沙区联想ThinkSystem SR530服务器sensor sysbrd vol故障问题维修案例&#xff1b; 服务器型号是&#xff1a;Lenovo thinksystem sr530 g6服务器 服务器所在位置&#xff1a;广东省广州市南沙区 服务器故障问题&#xff1a;机房异常停电&#xff0c;来电后…

【Entity Framework】EF连接字符串和模型

【Entity Framework】EF连接字符串和模型 文章目录 【Entity Framework】EF连接字符串和模型一、概述二、使用 Code First 按约定创建连接三、使用 Code First 和指定的数据库名称按约定创建连接四、将 Code First 与 app.config/web.config 文件中的连接字符串结合使用五、将 …

请核对您的姓名、证件号码、有效期和年限是否选择正确,请勿使用挂失过的身份证

问题 请核对您的姓名、证件号码、有效期和年限是否选择正确&#xff0c;请勿使用挂失过的身份证 详细问题 笔者在专利业务办理系统进行新用户注册&#xff0c;注册时间为晚上大概22&#xff1a;00以后。注册时已核对姓名、证件号码、有效期和年限&#xff0c;已确保正确&…

LinkedHashMap部分底层源码解析

JDK版本为1.8.0_271&#xff0c;LinkedHashMap继承了HashMap&#xff0c;LinkedHashMap在HashMap的基础上维护了一个双向链表&#xff0c;实现了可以根据插入顺序/访问顺序&#xff08;accessOrderfalse/true&#xff09;访问Map集合。 关于HashMap的原理可以参考HashMap部分底…

RabbitMQ-死信队列常见用法

目录 一、什么是死信 二、什么是死信队列 ​编辑 三、第一种情景&#xff1a;消息被拒绝时 四、第二种场景&#xff1a;. 消费者发生异常&#xff0c;超过重试次数 。 其实spring框架调用的就是 basicNack 五、第三种场景&#xff1a; 消息的Expiration 过期时长或队列TTL…

基于特征的多模态生物信号信息检索与自相似矩阵:专注于自动分割

论文地址&#xff1a;Biosensors | Free Full-Text | Feature-Based Information Retrieval of Multimodal Biosignals with a Self-Similarity Matrix: Focus on Automatic Segmentation (mdpi.com) 论文源码&#xff1a;无 期刊&#xff1a;biosensors 这篇论文提出了一种基…

kafka(六)——存储策略

存储机制 kafka通过topic作为主题缓存数据&#xff0c;一个topic主题可以包括多个partition&#xff0c;每个partition是一个有序的队列&#xff0c;同一个topic的不同partiton可以分配在不同的broker&#xff08;kafka服务器&#xff09;。 关系图 partition分布图 名称为t…

利用细粒度检索增强和自我检查提升对话式问题解答能力

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Boosting Conversational Question Answering with Fine-Grained Retrieval-Augmentation and Self-Check 论文地址&#xff1a;https://arxiv.org/abs/2403.18243 检索增强生成…

程序“猿”自动化脚本(一)

1.剪贴板管理器&#x1f4cb; 您是否曾经发现自己在处理多个文本片段时忘记了复制的内容&#xff1f;有没有想过有一个工具可以跟踪您一天内复制的所有内容&#xff1f; 该自动化脚本会监视您复制的所有内容&#xff0c;将每个复制的文本无缝存储在时尚的图形界面中&#xff0c…

阿里云4核16G服务器可以用来做什么?

阿里云4核16G服务器可以用来做什么&#xff1f;可用来搭建游戏服务器&#xff0c;阿里云4核16G服务器10M带宽30元1个月、90元3个月&#xff0c;优惠活动 aliyunfuwuqi.com/go/youhui 阿里云4核16G服务器可以用来做什么&#xff1f;除了搭建游戏服务器&#xff0c;还可以用来哪…

基于 GPIO 、Pinctl子系统、设备树的LED 驱动程序

理论部分&#xff1a; 编写思路&#xff1a; GPIO 的地位跟其他模块&#xff0c;比如 I2C 、 UART 的地方是一样的&#xff0c;要使用某个引脚&#xff0c;需要先把引脚配置为 GPIO 功能&#xff0c;这要使用 Pinctrl 子系统&#xff0c;只需要在设备 树里指定就可以。在…

力扣HOT100 - 41. 缺失的第一个正数

解题思路&#xff1a; 原地哈希 就相当于&#xff0c;让每个数字n都回到下标为n-1的家里。 而那些没有回到家里的就成了孤魂野鬼流浪在外&#xff0c;他们要么是根本就没有自己的家&#xff08;数字小于等于0或者大于nums.size()&#xff09;&#xff0c;要么是自己的家被别…

springCloud项目打包 ,maven package或install打包报错

解决思路一&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version></plugin><plugin>&…

【应急响应事件】记一次矿机木马事件

事情起因&#xff0c;是因为实验室有一台服务器的占用率从开机启动就是100%&#xff0c;很怀疑就是中了某种矿机木马&#xff0c;拿去挖矿了&#xff0c;然后经过师兄的不懈努力&#xff0c;终于找到了木马文件&#xff0c;给他命名为virus_sample 然后我就拿着样本去逆了 木马…

OSCP靶场--Peppo

OSCP靶场–Peppo 考点(ident枚举服务用户名ssh登陆rbash绕过 docker提权) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.158.60 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-10 09:32 EDT Nmap scan report…

使用 Docker 部署 Linux-Command 命令搜索工具

1&#xff09;介绍 Linux-Command GitHub&#xff1a;https://github.com/jaywcjlove/linux-command Linux-Command 仓库搜集了 580 多个 Linux 命令&#xff0c;是一个非盈利性的仓库&#xff0c;生成了一个 Web 网站方便使用&#xff0c;目前网站没有任何广告&#xff0c;内…

T2.数据库原理

2.1 关系模型概述 1.域 域&#xff1a; 一组有相同数据类型的值得集合 2.笛卡尔积 笛卡尔积&#xff1a; 设任意的N个域D1,D2,…,Dn。 3、关系的定义和性质 &#xff08;1&#xff09;关系的数学定义&#xff1a; 在笛卡儿积中取出有实际意义的元组来构造关系。 关系也是…

C++11 数据结构1 线性表的概念,线性表的顺序存储,实现,测试

一 线性表的概念 线性结构是一种最简单且常用的数据结构。 线性结构的基本特点是节点之间满足线性关系。 本章讨论的动态数组、链表、栈、队列都属于线性结构。 他们的共同之处&#xff0c;是节点中有且只有一个开始节点和终端节点。按这种关系&#xff0c;可以把它们的所有…

leetcode每日一题第四十六天

递归解法 class Solution { public:int search(vector<int>& nums, int target) {return midsearch(nums,target,0,nums.size()-1);}int midsearch(vector<int>& nums, int target, int low,int high){if(low < high){int mid (lowhigh) / 2;if(nums[…