HarmonyOS开发实战:如何实现一个运动排名榜页面

HarmonyOS开发实战:如何实现一个运动排名榜页面

代码仓库: 运动排名榜页面

项目介绍

本项目使用声明式语法和组件化基础知识,搭建一个可刷新的排行榜页面。在排行榜页面中,使用循环渲染控制语法来实现列表数据渲染,使用@Builder创建排行列表布局内容,使用装饰器@State、@Prop、@Link来管理组件状态。最后我们点击系统返回按键,来学习自定义组件生命周期函数。完成效果如图所示:

在这里插入图片描述

新建项目工程

选择Create Project新建项目,点击Application选择第一个Empty Ability应用,点击“Next”进行下一步
在这里插入图片描述
配置页中,详细信息如下:

Project name是开发者可以自行设置的项目名称,这里根据自己选择修改为自己项目名称。
Bundle name是包名称,默认情况下应用ID也会使用该名称,应用发布时对应的ID需要保持一致。
Save location为工程保存路径,建议用户自行设置相应位置。
Compile SDK是编译的API版本,这里默认选择API9。
Model选择Stage模型,其他保持默认即可。
点击“Finish”进行下一步
在这里插入图片描述

项目创建成功
在这里插入图片描述

代码实现

编写应用入口页面

RankPage是应用入口页面

@Entry
@Component
struct RankPage {@State message: string = 'My Ranking'build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)}.width('100%')}.height('100%')}
}

修改EntryAbility.ts应用配置,入口页面更改为pages/RankPage
在这里插入图片描述
运行成功
在这里插入图片描述

编写公共常量

公共常量的好处包括:

  • 代码可读性: 使用公共常量可以提高代码的可读性和可维护性,因为它们可以清晰地表达出程序中使用的固定数值或字符串。
  • 便于修改和维护: 如果程序中的某个数值或字符串需要修改,只需修改公共常量的定义,而不需要在整个程序中逐个修改。
  • 避免魔法数值: 使用公共常量可以避免在代码中出现“魔法数值”,即难以理解和维护的硬编码数值。
  • 提高代码重用性: 公共常量可以在整个程序中被引用和使用,从而提高代码的重用性。
  • 统一管理: 将所有的固定数值或字符串集中管理在公共常量中,有利于统一管理和维护。
/*** The font size of application.*/
export enum FontSize {SMALL = 14,MIDDLE = 16,LARGE = 20,
};/*** The font weight of application.*/
export enum FontWeight {BOLD = '400',BOLDER = '500',
};/*** The weight is global default value for component size.*/
export const WEIGHT = '100%';/*** The duration of toast.*/
export const TIME = 1000;/*** The interval time of exit.*/
export const APP_EXIT_INTERVAL: number = 4500;/*** The tag is the page name,which is used to print.*/
export const TAG: string = 'RankPage';/*** The title of TitleComponent.*/
export const TITLE: Resource = $r('app.string.title');class style {RANK_PADDING: number = 15;CONTENT_WIDTH: string = '90%';BORDER_RADIUS: number = 20;STROKE_WIDTH: number = 1;HEADER_MARGIN_TOP: number = 20;HEADER_MARGIN_BOTTOM: number = 15;LIST_HEIGHT: string = '65%';
}/*** The Style of RankPage.*/
export const Style: style = {/*** The padding of ranking.*/RANK_PADDING: 15,/*** The width of ranking content.*/CONTENT_WIDTH: '90%',/*** The border radius.*/BORDER_RADIUS: 20,/*** The stroke width of divider.*/STROKE_WIDTH: 1,/*** The top margin of ranking header.*/HEADER_MARGIN_TOP: 20,/*** The bottom margin of ranking header.*/HEADER_MARGIN_BOTTOM: 15,/*** The height of list.*/LIST_HEIGHT: '65%'
};class listHeaderStyle {FONT_WEIGHT: number = 400;LAYOUT_WEIGHT_LEFT: string = '30%';LAYOUT_WEIGHT_CENTER: string = '50%';LAYOUT_WEIGHT_RIGHT: string = '20%';
}/*** The Style of ListHeaderComponent.*/
export const ListHeaderStyle: listHeaderStyle = {/*** The weight of font.*/FONT_WEIGHT: 400,/*** The layout weight of left.*/LAYOUT_WEIGHT_LEFT: '30%',/*** The layout weight of center.*/LAYOUT_WEIGHT_CENTER: '50%',/*** The layout weight of right.*/LAYOUT_WEIGHT_RIGHT: '20%',
};class itemStyle {TEXT_LAYOUT_SIZE: number = 24;CIRCLE_TEXT_BORDER_RADIUS: number = 24;CIRCLE_TEXT_SIZE: number = 24;CIRCLE_TEXT_COLOR_STOP_1: number = 0.5;CIRCLE_TEXT_COLOR_STOP_2: number = 1.0;BAR_HEIGHT: number = 48;LAYOUT_WEIGHT_LEFT: string = '30%';LAYOUT_WEIGHT_CENTER: string = '50%';LAYOUT_WEIGHT_RIGHT: string = '20%';BORDER_WIDTH: number = 1;COLOR_GREEN: Resource = $r('app.color.item_color');COLOR_BLACK: Resource = $r('app.color.item_color_black');
}/*** The Style of ListItemComponent.*/
export const ItemStyle: itemStyle = {/*** The line height of text.*/TEXT_LAYOUT_SIZE: 24,/*** The border radius of circle text.*/CIRCLE_TEXT_BORDER_RADIUS: 24,/*** The size of circle text.*/CIRCLE_TEXT_SIZE: 24,/*** Gradient color proportion.*/CIRCLE_TEXT_COLOR_STOP_1: 0.5,/*** Gradient color proportion.*/CIRCLE_TEXT_COLOR_STOP_2: 1.0,/*** The height of item.*/BAR_HEIGHT: 48,/*** The layout weight of left.*/LAYOUT_WEIGHT_LEFT: '30%',/*** The layout weight of center.*/LAYOUT_WEIGHT_CENTER: '50%',/*** The layout weight of right.*/LAYOUT_WEIGHT_RIGHT: '20%',/*** The width of border.*/BORDER_WIDTH: 1,/*** The green color of item.*/COLOR_GREEN: $r('app.color.item_color'),/*** The black color of item.*/COLOR_BLACK: $r('app.color.item_color_black')
};class titleBarStyle {IMAGE_BACK_SIZE: number = 21;IMAGE_BACK_MARGIN_RIGHT: number = 18;IMAGE_LOADING_SIZE: number = 22;BAR_HEIGHT: number = 47;BAR_MARGIN_HORIZONTAL: number = 26;BAR_MARGIN_TOP: number = 10;WEIGHT: string = '50%';
}/*** The Style of TitleComponent.*/
export const TitleBarStyle: titleBarStyle = {/*** The image size of back button.*/IMAGE_BACK_SIZE: 21,/*** The right margin of back button.*/IMAGE_BACK_MARGIN_RIGHT: 18,/*** The size of loading image.*/IMAGE_LOADING_SIZE: 22,/*** The height of TitleComponent.*/BAR_HEIGHT: 47,/*** The horizontal margin of TitleComponent.*/BAR_MARGIN_HORIZONTAL: 26,/*** The top margin of TitleComponent.*/BAR_MARGIN_TOP: 10,/*** The weight of Row layout.*/WEIGHT: '50%',
};

静态资源

静态资源从代码仓库去获取
在这里插入图片描述

实现标题组件

TitleComponent.ets代码实现

import AppContext from '@ohos.app.ability.common';
import { FontSize, TitleBarStyle, WEIGHT } from '../common/constants/Constants';// 标题组件
@Component
export struct TitleComponent {@Link isRefreshData: boolean; // 是否刷新数据@State title: Resource = $r('app.string.title_default'); // 标题build() {Row() {Row() {// 返回箭头Image($r('app.media.ic_public_back')).height(TitleBarStyle.IMAGE_BACK_SIZE) // 高度.width(TitleBarStyle.IMAGE_BACK_SIZE) // 宽度.margin({ right: TitleBarStyle.IMAGE_BACK_MARGIN_RIGHT }) // 外边距.onClick(() => { // 返回上一个界面let handler = getContext(this) as AppContext.UIAbilityContext;handler.terminateSelf();})Text(this.title) // 标题.fontSize(FontSize.LARGE)}.width(TitleBarStyle.WEIGHT).height(WEIGHT).justifyContent(FlexAlign.Start) // 水平起始位置对齐// 刷新图标Row() {Image($r('app.media.loading')).height(TitleBarStyle.IMAGE_LOADING_SIZE).width(TitleBarStyle.IMAGE_LOADING_SIZE).onClick(() => { // 点击刷新列表数据this.isRefreshData = !this.isRefreshData;})}.width(TitleBarStyle.WEIGHT).height(WEIGHT).justifyContent(FlexAlign.End)}.width(WEIGHT).padding({ left: TitleBarStyle.BAR_MARGIN_HORIZONTAL,right: TitleBarStyle.BAR_MARGIN_HORIZONTAL }).margin({ top: TitleBarStyle.BAR_MARGIN_TOP }).height(TitleBarStyle.BAR_HEIGHT).justifyContent(FlexAlign.SpaceAround)}
}

应用入口页RankPage引入TitleComponent组件

import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';@Entry
@Component
struct RankPage {@State isSwitchDataSource: boolean = true; // 是否切换数据源build() {Column() {// 标题TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })}}
}

运行代码:
在这里插入图片描述

实现列表头部

ListHeaderComponent .ets代码实现

import { FontSize, ListHeaderStyle } from '../common/constants/Constants';@Component
export struct ListHeaderComponent {paddingValue: Padding | Length = 0; // 内边距widthValue: Length = 0; // 宽度build() {Row() {Text('排名').fontSize(FontSize.SMALL) // 字体大小.width(ListHeaderStyle.LAYOUT_WEIGHT_LEFT) // 宽度.fontWeight(ListHeaderStyle.FONT_WEIGHT) // 字体宽度.fontColor($r('app.color.font_description')) // 字体颜色Text('姓名').fontSize(FontSize.SMALL).width(ListHeaderStyle.LAYOUT_WEIGHT_CENTER).fontWeight(ListHeaderStyle.FONT_WEIGHT).fontColor($r('app.color.font_description'))Text('步数').fontSize(FontSize.SMALL).width(ListHeaderStyle.LAYOUT_WEIGHT_RIGHT).fontWeight(ListHeaderStyle.FONT_WEIGHT).fontColor($r('app.color.font_description'))}.width(this.widthValue) // 宽度.padding(this.paddingValue) // 内边距}
}

应用入口页RankPage引入ListHeaderComponent 组件

import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';
import { ListHeaderComponent } from '../view/ListHeaderComponent';@Entry
@Component
struct RankPage {@State isSwitchDataSource: boolean = true; // 是否切换数据源build() {Column() {// 标题TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })// 列表头部ListHeaderComponent({paddingValue: {left: Style.RANK_PADDING,right: Style.RANK_PADDING},widthValue: Style.CONTENT_WIDTH}).margin({ // 外边距top: Style.HEADER_MARGIN_TOP,bottom: Style.HEADER_MARGIN_BOTTOM})}}
}

运行代码:
在这里插入图片描述

准备排名榜数据

RankData.ets 排序类

// 排名类
export class RankData {name: string; // 姓名stepNum: string; // 步数id: string;// 构造函数constructor(id: string, name: string, stepNum: string) {this.id = id;this.name = name;this.stepNum = stepNum;}
}

DataModel.ets初始化排名数据

import { RankData } from '../viewmodel/RankData';export { rankData1, rankData2 }// 初始化排名数据1
const rankData1: RankData[] = [new RankData('1', '喜羊羊', '12080'),new RankData('2', '美羊羊', '10320'),new RankData('3', '灰太狼', '9801'),new RankData('4', '红太狼', '8431'),new RankData('5', '懒羊羊', '7546'),new RankData('6', '暖羊羊', '7431'),new RankData('7', '沸羊羊', '7187'),new RankData('8', '蕉太狼', '7003'),new RankData('9', '小灰灰', '6794'),new RankData('10', '慢羊羊', '6721')
];// 初始化排名数据2
const rankData2: RankData[] = [new RankData('11', '曹操', '8836'),new RankData('12', '马超', '8521'),new RankData('13', '关羽', '8431'),new RankData('14', '吕布', '7909'),new RankData('15', '张飞', '7547'),new RankData('16', '赵云', '7433'),new RankData('17', '刘备', '7186'),new RankData('18', '孙策', '7023'),new RankData('19', '黄忠', '6794'),new RankData('20', '许褚', '6721')
];

RankViewModel.ets获取排序数据

import { RankData } from './RankData';
import { rankData1, rankData2 } from '../model/DataModel';// 获取排序数据
export class RankViewModel {loadRankDataSource1(): RankData[] {return rankData1;}loadRankDataSource2(): RankData[] {return rankData2;}
}

RankPage.ets引入排名数据源

  • let rankModel: RankViewModel = new RankViewModel();
  • 通过aboutToAppear函数初始化数据源
import { RankViewModel } from '../viewmodel/RankViewModel';
import { RankData } from '../viewmodel/RankData';
import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';
import { ListHeaderComponent } from '../view/ListHeaderComponent';let rankModel: RankViewModel = new RankViewModel();@Entry
@Component
struct RankPage {@State dataSource1: RankData[] = [];@State dataSource2: RankData[] = [];@State isSwitchDataSource: boolean = true; // 是否切换数据源// 初始化数据源aboutToAppear() {this.dataSource1 = rankModel.loadRankDataSource1();this.dataSource2 = rankModel.loadRankDataSource2();}build() {Column() {// 标题TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })// 列表头部ListHeaderComponent({paddingValue: {left: Style.RANK_PADDING,right: Style.RANK_PADDING},widthValue: Style.CONTENT_WIDTH}).margin({ // 外边距top: Style.HEADER_MARGIN_TOP,bottom: Style.HEADER_MARGIN_BOTTOM})}}
}

实现排名列表

ListItemComponent .ets代码实现

import { FontSize, FontWeight, ItemStyle, WEIGHT } from '../common/constants/Constants';@Component
export struct ListItemComponent {index?: number;private name?: string;stepNum: string = '';@State isChange: boolean = false;build() {Row() {// 排名Column() {if (this.isRenderCircleText()) {this.CircleText(this.index);} else {Text(this.index?.toString()).lineHeight(ItemStyle.TEXT_LAYOUT_SIZE) // 行高.textAlign(TextAlign.Center) // 文本居中.width(ItemStyle.TEXT_LAYOUT_SIZE) // 宽度.fontWeight(FontWeight.BOLD) // 字体宽度.fontSize(FontSize.SMALL) // 字体大小}}.width(ItemStyle.LAYOUT_WEIGHT_LEFT) // 宽度.alignItems(HorizontalAlign.Start) // 垂直起始位置对齐// 姓名Text(this.name).width(ItemStyle.LAYOUT_WEIGHT_CENTER).fontWeight(FontWeight.BOLDER).fontSize(FontSize.MIDDLE)// ture:绿色字体,false:黑色字体.fontColor(this.isChange ? ItemStyle.COLOR_GREEN : ItemStyle.COLOR_BLACK)// 步数Text(this.stepNum).width(ItemStyle.LAYOUT_WEIGHT_RIGHT).fontWeight(FontWeight.BOLD).fontSize(FontSize.SMALL).fontColor(this.isChange ? ItemStyle.COLOR_GREEN : ItemStyle.COLOR_BLACK)}.height(ItemStyle.BAR_HEIGHT).width(WEIGHT).onClick(() => { // 点击事件this.isChange = !this.isChange;})}// 圆圈背景@Builder CircleText(index: number) {Row() {Text(this.index?.toString()).fontWeight(FontWeight.BOLD).fontSize(FontSize.SMALL).fontColor(Color.White);}.justifyContent(FlexAlign.Center).borderRadius(ItemStyle.CIRCLE_TEXT_BORDER_RADIUS).size({ width: ItemStyle.CIRCLE_TEXT_SIZE,height: ItemStyle.CIRCLE_TEXT_SIZE }).backgroundColor($r('app.color.circle_text_background'))}// 是否显示圆圈isRenderCircleText(): boolean {return this.index === 1 || this.index === 2 || this.index === 3;}
}

应用入口页RankPage引入ListItemComponent组件

  • @Builder RankList装饰的方法用于定义组件的声明式UI描述,在一个自定义组件内快速生成多个布局内容。
import { RankViewModel } from '../viewmodel/RankViewModel';
import { RankData } from '../viewmodel/RankData';
import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';
import { ListHeaderComponent } from '../view/ListHeaderComponent';
import { ListItemComponent } from '../view/ListItemComponent';let rankModel: RankViewModel = new RankViewModel();@Entry
@Component
struct RankPage {@State dataSource1: RankData[] = [];@State dataSource2: RankData[] = [];@State isSwitchDataSource: boolean = true; // 是否切换数据源// 初始化数据源aboutToAppear() {this.dataSource1 = rankModel.loadRankDataSource1();this.dataSource2 = rankModel.loadRankDataSource2();}build() {Column() {// 标题TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })// 列表头部ListHeaderComponent({paddingValue: {left: Style.RANK_PADDING,right: Style.RANK_PADDING},widthValue: Style.CONTENT_WIDTH}).margin({ // 外边距top: Style.HEADER_MARGIN_TOP,bottom: Style.HEADER_MARGIN_BOTTOM})// 排名列表this.RankList(Style.CONTENT_WIDTH)}.backgroundColor($r('app.color.background')) // 背景色.height(WEIGHT) // 高度.width(WEIGHT) // 宽度}@Builder RankList(widthValue: Length) {Column() {List() { // 列表ForEach(this.isSwitchDataSource ? this.dataSource1 : this.dataSource2,(item: RankData, index?: number) => {ListItem() {ListItemComponent({ index: (Number(index) + 1), name: item.name, stepNum: item.stepNum})}}, (item: RankData) => JSON.stringify(item))}.width(WEIGHT) // 宽度.height(Style.LIST_HEIGHT) // 高度.divider({ strokeWidth: Style.STROKE_WIDTH }) // 分割线}.padding({ // 内边距left: Style.RANK_PADDING,right: Style.RANK_PADDING}).borderRadius(Style.BORDER_RADIUS) // 边框半径.width(widthValue) // 宽度.alignItems(HorizontalAlign.Center) // 垂直居中对齐.backgroundColor(Color.White) // 背景色}
}

运行代码:
在这里插入图片描述
刷新列表:
在这里插入图片描述

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

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

相关文章

【Unity自动寻路】使用Navigation系统实现物体自动寻路绕开障碍物

知识点流程图 自动导航Navigation系统 我们在游戏场景中经常会有一些障碍物、墙壁、树木等等,如果我想要让角色或者怪物去墙的另一边,我直接在墙另一边点击左键,我希望角色自动跑过去,但是他不能直接穿透墙,他需要“智…

安卓开发学习---kotlin版---笔记(二)

UI学习 UI分类 安卓的UI分为两大类:一类叫做View视图,一类叫做ViewGroup容器 View视图:TextView,Button,ImageView都是常见的视图ViewGroup容器:内部尅承载、放置、添加View视图的容器 布局方式 安卓布局主要有:线…

【智能算法】11种混沌映射算法+2种智能算法示范【鲸鱼WOA、灰狼GWO算法】

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 混沌映射算法是我们在智能算法改进中常用到的方法,本程序充分考虑改进算法应用的便捷性,集成了11种混合映射算法,包括Singer、tent、Logistic、Cubic、chebyshev、Piecewise…

原生html + vue3 获取引用元素refs - elementUI如何在setup中进行表单校验设置

背景: 原生Html 引入elementPlust vue3 ,需要在vue3 setup里做表单校验,通过el-form refform 的refs元素执行校验。 解决方案1: 保存vue挂载之后实例vm为一个常量,由实例来获取:vm.$refs.form.validate(…

iClient3D 图元操作

1. S3MTilesLayer,S3M(Spatial 3D Model)图层类 S3MTilesLayer,S3M(Spatial 3D Model)图层类,通过该图层实现加载三维切片缓存,包括倾斜摄影模型、BIM模型、点云数据、精细模型、矢量数据、符号等。 那S3MTilesLayer中针对图元的…

AI性能再提升12.5%,ZStack Cube 超融合一体机基于第五代英特尔®至强®可扩展处理器解决方案发布

12月15日,以“Al无处不在,创芯无所不及”为主题的2023英特尔新品发布会暨AI技术创新派对上,云轴科技ZStack与英特尔联合发布基于第五代英特尔 至强 可扩展处理器的 ZStack Cube 超融合一体机解决方案白皮书(简称解决方案&#xff…

二进制枚举算法

二进制 : 也就是只有0和1的进制表示 ; 二进制枚举算法 一个二进制数 x 可以表示 S 的一个子集,某个二进制位i上为0表示没有选i元素,为1表示选了该元素放入子集,比如13为1101就表示选了0,2,3号元素;对于一个长度为N的序列(也就是包含N个元素)有2^N个子…

C++之程序生成

一、C的发展史 截止到2023年12月,C已经更新了很多版本,并在每个版本中修复了bug和添加了新的特性,ISO C委员会每三年会对C进行一次更新: C98:于1998年发布,是最早的国际标准化版本。它包含了面向对象编程…

亚马逊云科技re_Invent 2023产品体验:亚马逊云科技产品应用实践 王炸产品Amazon Q,你的AI助手

本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 亚马逊云科技开发者社区, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 意料之中 2023年9月25日,亚马逊宣布与 Anthropic 正式展开战略合作&#x…

机器学习 | 决策树 Decision Tree

—— 分而治之,逐个击破 把特征空间划分区域 每个区域拟合简单模型 分级分类决策 1、核心思想和原理 举例: 特征选择、节点分类、阈值确定 2、信息嫡 熵本身代表不确定性,是不确定性的一种度量。 熵越大,不确定性越高,…

OpenAI 偷偷在训练 GPT-4.5!?

最近看到有人已经套路出 ChatGPT 当前的版本,回答居然是 gpt-4.5-turbo: 实际试验下,用 starflow.tech,切换到小星 4 全能版(同等官网最新 GPT-4),复制下面这段话问它: What is the…

人工智能在金融与商业领域的智能化变革

导言 随着人工智能技术的不断发展,金融和商业领域正迎来一场智能化的变革。随着人工智能的不断发展,其在金融和商业领域的应用正成为业界瞩目的焦点。本文将深入探讨人工智能在金融和商业应用中的关键技术、应用场景以及对未来的影响。 1. 关键技术与算…

数据结构:队列

数据结构:队列 文章目录 数据结构:队列1.队列常用操作:2.队列的实现3.队列典型应用 ***「队列 queue」是一种遵循先入先出规则的线性数据结构。***队列模拟了排队现象,即新来的人不断加入队列尾部,而位于队列头部的人逐…

ceph的osd盘删除操作和iscsi扩展

ceph的osd盘删除操作 拓展:osd磁盘的删除(这里以删除node1上的osd.0磁盘为例) 1, 查看osd磁盘状态 [rootnode1 ceph]# ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.00298 root default -3 0.00099 host node10 hdd 0.00…

微服务实战系列之ZooKeeper(下)

前言 通过前序两篇关于ZooKeeper的介绍和总结,我们可以大致理解了它是什么,它有哪些重要组成部分。 今天,博主特别介绍一下ZooKeeper的一个核心应用场景:分布式锁。 应用ZooKeeper Q:什么是分布式锁 首先了解一下&…

云原生向量计算引擎 PieCloudVector:为大模型提供独特记忆

拓数派大模型数据计算系统(PieDataComputingSystem,缩写:πDataCS)在10月24日程序员节「大模型数据计算系统」2023拓数派年度技术论坛正式发布。πDataCS 以云原生技术重构数据存储和计算,「一份存储,多引擎…

C# 基本桌面编程(二)

一、前言 本章为C# 基本桌面编程技术的第二节也是最后一节。前一节在下面这个链接 C# 基本桌面编程(一)https://blog.csdn.net/qq_71897293/article/details/135024535?spm1001.2014.3001.5502 二、控件布局 1 叠放顺序 在WPF当中布局,通…

华为配置OSPF与BFD联动示例

组网需求 如图1所示,SwitchA、SwitchB和SwitchC之间运行OSPF,SwitchA和SwitchB之间的交换机仅作透传功能。现在需要SwitchA和SwitchB能快速感应它们之间的链路状态,当链路SwitchA-SwitchB发生故障时,业务能快速切换到备份链路Swi…

极狐GitLab DevSecOps 之容器镜像安全扫描

容器镜像安全 现状 最近某银行遭受供应链攻击的事件传的沸沸扬扬,安全又双叒叕进入了人们的视野。安全确实是一个非常重要,但是又最容易被忽略的话题。但是现在到了一个不得不人人重视安全,人人为安全负责的时代。尤其以现在非常火爆的云原…

java设计模式-工厂方法模式

1.工厂方法(FactoryMethod)模式的定义 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。 2.工厂方法模式的主要优缺点 优点: 用户只需要知道具体工厂的名称…