关于鸿蒙的笔记整理
提示:有使用过 vue 或 react 的小伙伴更容易理解
知识点强调
: ArkTS所有内容都不支持深层数据更新 UI渲染
文章目录
- 一、关于样式
- 1 . 默认单位 vp
- 2 . 写公共样式
- 二 、 加载图片
- 三 、 自定义构建函数 @Builder
- 四、构建函数-@BuilderParam 传递UI
- 五 、 父子组件传值
- 六、组件状态 (state 组件内)
- 七、更新深层的数据
- 八 、应用状态
一、关于样式
1 . 默认单位 vp
答: vp 是 virtual pixel 的缩写,根据设备像素密度转化为屏幕物理像素,px 直接表示设备的像素,因为我们设备的分辨率密度不同,最好是使用 vp
适配: 可以使用伸缩布局layoutWeight,flex布局,网格系统,栅格系统布局,
2 . 写公共样式
在开发过程中会出现大量代码在进行重复样式设置,@Styles 和 Extend 可以帮我们进行样式复用
1. @styles 方式
- 只支持通用属性 和 通用事件,且不支持箭头函数语法
- 在组件内(局部)无需加 function , 在组件外(全局) 定义时要加function
@Styles function textStyle () {.width(100).height(50).backgroundColor(Color.Pink).borderRadius(25).onClick(() => {promptAction.showToast({message: "测试"})})
}
2. Extend 方式
- 使用 @Extend 装饰器修饰的函数只能是 全局
- 且参数可以是一个函数,实现复用事件且可处理不同逻辑
- 函数可以进行 传参,如果参数是状态变量,状态更新后会刷新UI
// 全局 原生组件 参数
// ↓ ↓ ↓
@Extend(Text) function textInputAll (callback?: () => void) {.width(100).height(50).backgroundColor(Color.Pink).borderRadius(25).textAlign(TextAlign.Center).fontColor(Color.White).onClick(() => {callback && callback()})
}
二 、 加载图片
- 使用本地图片
// 可以新建一个文件夹,里面放本地图片(ets下)
Image('/assets/a.png')
- 使用 resource 下的 media 图片
// resource/media (a 是文件名,扩展名省略)
Image($r('/app.media.a'))
- 使用 resource 下的 rawfile 图片
// resource/rawfile
Image($rawfile('a.png'))
- 使用网络图片(必须申请网络权限)
// resource/rawfile
Image("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F2bf1b169-d217-44c3-a5b3-dd00813bc20d%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1704614176&t=e15a2fd5193aeeb24fc95b5dbe395907")
"requestPermissions": [{"name":"ohos.permission.INTERNET"
}],
三 、 自定义构建函数 @Builder
如果你不想在直接抽象组件, ArkUI 还提供了一种更轻量的UI元素复用机制
@Builder
,可以将重复使用的 UI 元素抽象成一个方法,在 build 方法里调用。称之为自定义构建函数
- 使用@Builder 定义一个函数(全局加function)
- 在组件里使用这个函数
// 定义 Builder
@Builder
function getCellContent(leftTitle: string, rightValue: string) {Row() {Row() {Text(leftTitle)Text(rightValue)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left: 15,right: 15}).borderRadius(8).height(40).backgroundColor(Color.White)}.padding({left: 10,right: 10})}
class CardClass {time: string = ""location: string = ""type: string = ""
}
@State formData: CardClass = {time: "2023-12-12",location: '回龙观',type: '漏油'}
// 在组件里使用
Column({ space: 10 }) {getCellContent("异常时间", this.formData.time)getCellContent("异常位置", this.formData.location)getCellContent("异常类型", this.formData.type)Button("修改数据").onClick(() => {this.formData.location = "望京"})}.width('100%')
全局自定义函数的问题
-
全局的自定义构建函数可以被整个应用获取(下一代可用-当前4.0暂不支持),不允许使用this和bind方法。
-
不可被其他文件引用
-
当我点击按钮时数据即使是响应式的,当数据发生改变,该函数不会自动渲染
- 因为我们刚刚传过去的是一个string类型, string 类型是一个基础类型,按值传递,不具备响应式更新的特点
解决方案:改为按引用传递
- 因为我们刚刚传过去的是一个string类型, string 类型是一个基础类型,按值传递,不具备响应式更新的特点
// 完整代码
@Entry
@Component
struct BuilderCase {@State formData: CardClass = {time: "2023-12-12",location: '回龙观',type: '漏油'}@BuildergetCellContent($$: CellParams) {Row() {Row() {Text($$.leftTitle)Text($$.rightValue)}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({left: 15,right: 15}).borderRadius(8).height(40).backgroundColor(Color.White)}.padding({left: 10,right: 10})}build() {Row() {Column() {Column({ space: 10 }) {this.getCellContent({ leftTitle: '异常时间', rightValue: this.formData.time })this.getCellContent({ leftTitle: '异常位置', rightValue: this.formData.location })this.getCellContent({ leftTitle: '异常类型', rightValue: this.formData.type })}.width('100%')Button("修改数据").onClick(() => {this.formData.location = "望京"})}.width('100%')}.height('100%').backgroundColor('#ccc')}
}class CardClass {time: string = ""location: string = ""type: string = ""
}
class CellParams {leftTitle: string = ""rightValue: string = ""
}
四、构建函数-@BuilderParam 传递UI
Vue里面有个叫做slot插槽的东西,就是可以传入自定义的结构,整体复用父组件的外观
ArkTS提供了一个叫做BuilderParam的修饰符,你可以在组件中定义这样一个函数属性,在使用组件时直接传入
- 使用@BuilderParam 声明一个组件,子组件要在想要显示插槽的地方来调用传入的方法
- 在父组件里调用并传入,父组件传递是一个函数,这个函数也要使用 @Builder 修饰
// 使用BuilderParam 声明组件
@Component
struct HMCard {@BuilderParamcontent: () => voidbuild() {Column () {Text("卡片组件")Divider()Text("传入内容")if(this.content) {this.content() // 子组件要在想要显示插槽的地方来调用传入的方法}}}
}
@Entry
@Component
struct BuilderParamCase {
// 声明渲染的函数组件@BuildergetContent () {Row() {Text("插槽内容").fontColor(Color.Red)}}build() {Row() {Column() {HMCard({ content: this.getContent }) // 调用组件并传入要渲染的函数}.width('100%')}.height('100%')}
}
五 、 父子组件传值
父传子
// 父组件的子组件上,传递一个对象(HmCommentItem)HmCommentItem({ item:item})
// 子组件上进行接收item: Partial<ReplyItem> = {} // 默认是public
- item 默认是用 public 修饰的,第一次渲染数据是准确的,当父组件的值发生改变时,子组件是不会改变的
- 如果想让子组件跟着发生改变,看下面的组件共享
子传父
(目的是修改父组件的值)
// 父组件的子组件上,传递一个方法(HmCommentItem)HmCommentItem({ item:item,changeLike:(item)=>{this.changeLike(item)}})
// 子组件上进行接收
changeLike: (params: ReplyItem) => void = () => {} // 接受一个无返回值的方法,默认是空函数
六、组件状态 (state 组件内)
状态共享 (父子单向)
// 子组件上进行接收@Prop item: Partial<ReplyItem>
- Prop只能修饰string number boolean类型的数据- (Next全部都支持了各种类型),Prop 只会在当前子组件生效,不会传到父组件
- 在子组件里是不能直接修改父组件的值
状态共享 (父子双向)
- 在上面我们用了 Prop 可以在父组件里修改数据,子组件也会同步数据,
- 但是prop 的作用在当前的组件,
- @Link , 可以实现父子同步
// 子组件上进行接收@Link item: Partial<ReplyItem>
ps :
Link修饰的数据必须得是最外层的 State数据,也就是说不能是数组对象的某一项
状态共享 (后代组件)
- 如果我们的组件层级特别多,ArkTS支持跨组件传递状态数据来实现双向同步@Provide和 @Consume
- 这特别像Vue中的依赖注入
假设我们有三层组件,Index-Child-Grand,
Index的数据不想经过Child而直接给到Grand可以使用该修饰器@Entry
@Component
struct ProvideCase02 {@Provide count: number = 0build() {Row() {Column({ space: 15 }) {Text(this.count.toString()).fontSize(50)Button("顶级组件+1").onClick(() => {this.count++})Divider()Child()}.width('100%')}.height('100%')}
}@Component
struct Child {build() {Column() {Text("子组件").fontSize(40)Divider()Grand()}}
}@Component
struct Grand {@Consume count: numberbuild() {Column() {Text("孙组件").fontSize(30)Text(this.count.toString())}}
}
注意:这是双向的修改数据
状态共享 (状态监听器)
- 如果开发者需要关注某个状态变量的值是否改变,可以使用 @Watch 为状态变量设置回调函数。
- Watch(“回调函数名”)中的回调必须在组件中声明,该函数接收一个参数,参数为修改的属性名
- Watch修饰符要写在 State Prop Link Provide的修饰符下面,否则会有问题
● 在第一次初始化的时候,@Watch装饰的方法不会被调用
@Provide('aa')@Watch('updateCount')count: number = 0updateCount(keyName: string) {promptAction.showToast({message: this.count.toString()})console.log(keyName,this.count.toString())
}
状态共享 (@Observed 、@ObjectLink)
之前讲解Link的时候,我们遇到了一个问题,就是循环生成的item没办法用item传递给子组件的Link,也就是封装的组件没办法做双向更新同步,那么ArtTS支持 Observed和@ObjectLink来实现这个需求
使用步骤:
● 类 class 数据需要定义通过构造函数,使用 @Observed 修饰这个类
● 初始化数据:需要通过初始化构造函数的方式添加
● 通过 @ObjectLink 关联对象,可以直接修改被关联对象来更新UI
@Entry
@Component
struct ObjectLinkCase {@State message: string = 'Hello World'// 定义数据时,使用new创建对象,之前是字面量创建// 原因:@Statelist: FoodObjectClass[] = [new FoodObjectClass({order_id: 1,food_name: '鱼香肉丝',food_price: 18.8,food_count: 1}) ,new FoodObjectClass({order_id: 2,food_name: '粗溜丸子',food_price: 26,food_count: 2}) , new FoodObjectClass({order_id: 3,food_name: '杂粮煎饼',food_price: 12,food_count: 1}) ]build() {Row() {Column({ space: 20 }) {ForEach(this.list, (item: FoodObjectClass) => {FoodItem({ item: item })})BottomCart({ myList: $list })}.width('100%')}.height('100%')}
}
@Extend(Text)
function TextStyle () {.layoutWeight(1).textAlign(TextAlign.Center).fontSize(20)
}@Extend(Text)
function AddCutStyle () {.width(40).height(40).borderRadius(20).backgroundColor(Color.Grey).textAlign(TextAlign.Center).fontSize(20)
}@Component
struct FoodItem {// 步骤二 : Observed必须和ObjectLink才有UI更新的效果@ObjectLinkitem: FoodObjectClassbuild() {Row() {Text(this.item.food_name).TextStyle()Text(this.item.food_price.toFixed(2)).TextStyle()Row() {Text("-").AddCutStyle().onClick(() => {this.item.food_count--}).visibility(this.item.food_count > 0 ? Visibility.Visible : Visibility.Hidden)Text(this.item.food_count.toString()).TextStyle().visibility(this.item.food_count > 0 ? Visibility.Visible : Visibility.Hidden)Text("+").AddCutStyle().onClick(() => {this.item.food_count++})}.layoutWeight(1)}.width('100%').height(40)}
}// 底部组件
@Component
struct BottomCart {@LinkmyList: FoodObjectClass[]build() {Button("更改菜品的数量").onClick(() => {this.myList = this.myList.map(item => {item.food_count++return item})})}
}
// 初始化数据 : 定义了一个接口
interface IFoodInfo {order_id: numberfood_name: stringfood_price: numberfood_count: number
}// 步骤一 : 食品类
// implements : 使用接口
@Observed
class FoodObjectClass implements IFoodInfo {order_id: number = 0food_name: string = ""food_price: number = 0food_count: number = 0constructor(obj: IFoodInfo) {this.order_id = obj.order_idthis.food_name = obj.food_namethis.food_price = obj.food_pricethis.food_count = obj.food_count}
}
注意:
-
interface声明类型不需要给初始值,class声明类型必须给初始值(next 版本要求)
-
使用了Observed这个装饰器来修饰class,那么只要我们改动class的属性,它就会驱动UI的更新(只是第一层,多层怎么办,往下看)
-
只有Observed修饰的class才可以被 ObjectLink使用,并且Entry修饰的组件不允许使用ObjectLink
-
ObjectLink只能修饰被Observed修饰的class类型
-
Observed修饰的class的数据如果是复杂数据类型,需要采用赋值的方式才可以具备响应式特性-因为它监听的是该属性的set和get
总结:
( State组件内状态)
- Prop 子组件修饰符 -4.0 boolean/number/string- 单向数据流
- Link 子组件修饰符-双向数据流,所有类型都支持- 必须通过$前缀-(循环数据就没有办法传入)
- Provide和Consume 双向数据流-所有结构均支持
- Watch 可以监听State Link Prop ObjectLink的数据变化
- Observed和ObjectLink
七、更新深层的数据
我们都知道 ArkTS 所有内容都不支持深层数据更新 UI渲染 , next 版本取消了 解构赋值我们怎么办呢?
- 对于对象类型的数据,我们多定义了一个接口 ( 看 flag1)
- 修改值时,我们传入 class 里 (看flag2)
@Entry
@Component
struct MulitiStateCase {@Stateuser: IUserProfileModel = new IUserProfileModel({username: '老高',age: 34,sex: "男",address: new IAddressModel({province: '河北',city: '衡水',area: '深州'})})build() {Row() {Column() {// UI更新只能监听到一层Row() {Text(this.user.username).fontSize(40)Text(this.user.age.toString()).fontSize(40)Text(this.user.address.province).fontSize(40)Text(this.user.address.city).fontSize(40)Text(this.user.address.area).fontSize(40)}.width('100%').height(50)Button("更新名字和年龄").onClick(() => {// this.user.username = "老高坏坏的"// this.user.age = 25this.user.address.city = "廊坊"this.user.address = new IAddressModel(this.user.address)})}.width('100%')}.height('100%')}
}
// flag1
interface IAddress {province: stringcity: stringarea: string
}interface IUserProfile {username: stringage: numbersex: '男' | '女'address: IAddress
}
export class IAddressModel implements IAddress {province: string = ''city: string = ''area: string = ''constructor(model: IAddress) {this.province = model.provincethis.city = model.citythis.area = model.area}
}
export class IUserProfileModel implements IUserProfile {username: string = ''age: number = 0sex: '男' | '女' = '男'address: IAddress = new IAddressModel({} as IAddress)constructor(model: IUserProfile) {this.username = model.usernamethis.age = model.agethis.sex = model.sexthis.address = model.address}
}
八 、应用状态
ArtTS提供了好几种状态用来帮助我们管理我们的全局数据
- State组件内状态
- LocalStorage - UIAbility状态(ps1)
- AppStorage - 应用内状态-多UIAbility共享-(内存-非持久化-退出应用同样消失)
- PersistenStroage-全局持久化状态(写入磁盘-持久化状态-退出应用 数据同样存在)
- ps1:前端localStorage 是写入磁盘的,所以是持久化;鸿蒙的LocalStorage 是写入内存的,当应用关闭了,数据清除了
LocalStorage:
- localStorage 是页面级的UI状态存储,一个应用可能有若干个UIAbility
- 通过 @Entry 装饰器接收的参数可以在页面内共享同一个 LocalStorage 实例。 LocalStorage 也可以在 UIAbility 内,页面间共享状态。
用法
创建 LocalStorage 实例:const storage = new LocalStorage({ key: value })
- 单向 @LocalStorageProp(‘user’) 组件内可变
- 双向 @LocalStorageLink(‘user’) 全局均可变
import router from '@ohos.router'// 步骤一: 定义数据
export class UserInfoClass {name: string = ""age: number = 0
}
let user: Record<string, UserInfoClass> = { "user": {name: '老高',age: 34
}};
// 步骤二:存数据
let storage: LocalStorage = new LocalStorage(user);
// ps: entry 这里需要先接受
@Entry(storage)
@Component
struct LocalStorageCase {@State message: string = 'Hello World'// 步骤三: 取数据 ( @LocalStorageProp 数据流是单向的,说明不能修改)@LocalStorageProp("user")myUser: UserInfoClass = {}build() {Row() {Column({ space: 15 }) {// 步骤四 : 当做变量就可以直接使用了Text("姓名:" + this.myUser.name)Text("年龄:" + this.myUser.age)Button("跳转到另一个页面").onClick(() => {router.pushUrl({url: 'pages/LocalStorageCase2'})})}.width('100%')}.height('100%')}
}
AppStorage :
- AppStorage 是应用全局的UI状态存储,是和应用的进程绑定的
- 由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。注意它也是内存数据,不会写入磁盘
用法:
- 使用UI修饰符
● 如果是初始化使用 AppStorage.SetOrCreate(key,value)
● 单向 @StorageProp(‘user’) 组件内可变
● 双向 @StorageLink(‘user’) 全局均可变 - 使用API方法
● AppStorage.Get(key) 获取数据
● AppStorage.Set(key,value) 覆盖数据
● const link: SubscribedAbstractProperty = AppStorage.Link(key) 覆盖数据
○ link.set(value) 修改
○ link.get() 获取
import router from '@ohos.router'
import promptAction from '@ohos.promptAction'
@Entry
@Component
struct AppStorageCase02 {@StorageProp("user_token")token: string = ''@StorageLink("user_token")linkToken: string = ''onPageShow() {promptAction.showToast({message: AppStorage.Get<string>("user_token") || '无token'})}build() {Row() {Column() {Text(this.token)Button("登录").onClick(() => {AppStorage.SetOrCreate<string>("user_token", "123456")router.pushUrl({url: 'pages/AppStorageCaseTrans'})})Button("修改token").onClick(() => {// this.linkToken = '678910'const link = AppStorage.Link("user_token") as SubscribedAbstractProperty<string>link.set("abcde")})}.width('100%')}.height('100%')}
}
PersistentStorage:
前面讲的所有状态均为内存状态,也就是应用退出便消失,所以如果我们想持久化的保留一些数据,应该使用 PersistentStorage
注意:
UI和业务逻辑不直接访问 PersistentStorage 中的属性,所有属性访问都是对 AppStorage 的访问,AppStorage 中的更改会自动同步到 PersistentStorage。也就是,我们和之前访问AppStorage是一样的,只不过需要提前使用PersistentStorage来声明
- PersistentStorage 将选定的 AppStorage 属性保留在设备磁盘上。
- 支持:number, string, boolean, enum 等简单类型;
- 如果:要支持对象类型,可以转换成json字符串
- 持久化变量最好是小于2kb的数据,如果开发者需要存储大量的数据,建议使用数据库api。
PersistentStorage.PersistProp("user_token", '') // 初始化磁盘
只要初始化了数据,我们以后使用AppStorage就可以读取和设置,它会自动同步到我们的磁盘上
目前不支持复杂对象的持久化,如果你需要存储,你需要把它序列化成功字符串
● 测试:需要在真机或模拟器调试
大家可以在上一个例子之前添加 PersistentStorage.PersistProp(‘属性名’, 值)
然后直接使用AppStorage进行Set就可以了,设置完成之后,使用模拟器先把任务销毁,然后再查看数据是否显示
相关文章:

关于鸿蒙的笔记整理
提示:有使用过 vue 或 react 的小伙伴更容易理解 知识点强调: ArkTS所有内容都不支持深层数据更新 UI渲染 文章目录 一、关于样式1 . 默认单位 vp2 . 写公共样式 二 、 加载图片三 、 自定义构建函数 Builder四、构建函数-BuilderParam 传递UI五 、 父子…...

【漏洞复现】先锋WEB燃气收费系统文件上传漏洞 1day
漏洞描述 /AjaxService/Upload.aspx 存在任意文件上传漏洞 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作…...

MYSQL篇--锁机制高频面试题
Mysql锁机制 1对mysql的锁有了解吗? 首先我们要知道,mysql的锁 其实是为了解决在并发事务时所导致的数据不一致问题的一种处理机制,也就是说 在事务的隔离级别实现中,就需要利用锁来解决幻读问题 然后我们可以聊到锁的分类 按锁…...

创建一个郭德纲相声GPTs
前言 在这篇文章中,我将分享如何利用ChatGPT 4.0辅助论文写作的技巧,并根据网上的资料和最新的研究补充更多好用的咒语技巧。 GPT4的官方售价是每月20美元,很多人并不是天天用GPT,只是偶尔用一下。 如果调用官方的GPT4接口&…...

靶机实战(10):OSCP备考之VulnHub Tre 1
靶机官网:Tre: 1[1] 实战思路: 一、主机发现二、端口发现(服务、组件、版本)三、漏洞发现(获取权限) 8082端口/HTTP服务 组件漏洞URL漏洞(目录、文件)80端口/HTTP服务 组件漏洞URL漏…...

在windows11系统上利用docker搭建linux记录
我的windows11系统上,之前已经安装好了window版本的docker,没有安装的小伙伴需要去安装一下。 下面直接记录安装linux的步骤: 一、创建linux容器 1、拉取镜像 docker pull ubuntu 2、查看镜像 docker images 3、创建容器 docker run --…...

swift对接环信sdk
准备 熟练objective-c语言 有一台mac电脑,并安装了xcode 和 cocoapods 内容篇幅较长,需要内心平和耐心看下去,务必戒躁. 学习目的 手把手教大家如何在iOS应用中集成环信IM 明确表示,内容一定全面,没有任何丢失,只要沉得住气,耐得下心,3小时即可搞定. 若经常阅读文档以及语…...

单片机中的PWM(脉宽调制)的工作原理以及它在电机控制中的应用。
目录 工作原理 在电机控制中的应用 脉宽调制(PWM)是一种在单片机中常用的控制技术,它通过调整信号的脉冲宽度来控制输出信号的平均电平。PWM常用于模拟输出一个可调电平的数字信号,用于控制电机速度、亮度、电压等。 工作原理 …...

css 怎么绘制一个带圆角的渐变色的边框
1,可以写两个样式最外面的div设置一个渐变的背景色。里面的元素使用纯色。但是宽高要比外面元素的小。可以利用里面的元素设置padding这样挡住部分渐变色。漏出来的渐变色就像边框一样。 <div class"cover-wrapper"> <div class"item-cover…...

Kotlin DSL C++项目引入OpenCV异常处理
现象 kotlin DSL(build.rgadle.kts)项目引入openCV sdk 编译提示Plugin [id: com.android.application, version: 8.2.1...错误 Plugin [id: com.android.application, version: 8.2.1, apply: false] was not found in any of the following sources:* Try: > Run with -…...

【微服务】 Spring cold、Kubernetes、Service mesh
目录 Spring Cloud # 什么是微服务?谈谈你对微服务的理解? # 什么是Spring Cloud? # springcloud中的组件有那些? # 具体说说SpringCloud主要项目? # Spring Cloud 和dubbo区别? # 服务注册和发现是什么意思?S…...

【scala】编译build报错 “xxx is not an enclosing class“
private[sources] val creationTimeMs: Long {val session SparkSession.getActiveSession.orElse(SparkSession.getDefaultSession)require(session.isDefined)private[xxx]是访问权限控制在xxxx包的意思。 解决办法: 把[sources]删掉,或者改成和包名…...

vue3+ts+vite项目从0 搭建,配置安装router/pinia/element-plus/scss等
一、安装vite环境 官网:https://cn.vitejs.dev/guide/why.html npm init vite1.选择vue 2.选择typescipt 3.创建成功 默认项目结构如下 4.安装项目依赖 npm install 5.启动项目 npm run dev二。安装配置scss 1.运行安装scss npm install -D sass sass-loa…...

华为OD机试 - 矩阵匹配(Java JS Python C)
题目描述 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式: N M K N*M矩阵 输出描述 N*M 的矩阵中可以选出 M! / N! 种组合数…...

使用ffmpeg实现音频静音修剪
1 silenceremove介绍 本文主要介绍在 FFmpeg 命令中使用 silenceremove filter 进行音频静音的修剪。 1.1 start_x参数 参数名说明取值范围默认值start_periods设置是否应在音频开头修剪音频。0 表示不应从一开始就修剪静音。当指定一个非 0 值时,它会修剪音频直…...

Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase解决大小写不一致问题 写在最前面全部过程Java equalsIgnoreCase() 方法idea中如何调试SpringBoot项目在IntelliJ IDEA中使用内置HTTP客户端设置断点和调试 补充&#x…...

Google Pixel 与 iPhone手机:哪个更好?
iPhone稳定可靠,Pixel性价比高且创新。两者各有千秋,满足不同需求 谷歌的 Pixel 手机是 Android 最接近 iPhone 的手机,也是真正原生的Android手机。在iPhone 15 Pro Max 与华为 Mate 60 Pro的比较中不难看出,iPhone依然有着极强…...

ddos攻击会让服务器受到什么影响?-速盾网络(sudun)
DDoS攻击是一种网络攻击手段,它通过利用大量的请求或恶意流量超过服务器的处理能力,从而导致服务器无法正常工作或服务质量显著下降。 首先,DDoS攻击会对服务器的带宽造成极大的压力。攻击者会利用大量的机器或网络资源发起攻击,…...

NSSCTF Interesting_include
开启环境: 通过审计,我们可知: flag在flag.php中,可以利用php中伪协议 payload:?filterphp://filter/readconvert.base64-encode/resourceflag.php 将其base64解码就是flag. NSSCTF{3dc54721-be9e-444c-8228-7133fba76ad4}...

IPv6路由协议---IPv6动态路由(OSPFv3-5)
OSPFv3各链路状态通告类型 4.Inter-Area-Router-LSA区域间路由器(4类LSA) 边界路由器(ABR)产生的第4类LSA,在Area 范围内泛洪,描述了到本AS内其他区域的ASBR路由器信息; 每各Inter-Area-Router-LSA包含一个ASBR路由器信息,LSA中的能力选项(Options)与所描述的ASBR …...

GPT Store开业大吉:一场AI技术与创新的盛宴
就在1.11 日,ChatGPT 正式上线 GPT Store ! OpenAI CEO 山姆奥特曼第一时间确认了这个消息: 自从GPTs的概念提出以来,短短两个月内,全球用户已经创造了超过300万个GPTs。 点击 GPT Store 或者进入ChatGpt页面&am…...

Linux---gcc编译
目录 前言 一、gcc编译 二、程序的编译过程 三、gcc查看编译过程 1.预处理阶段 2.编译 3.汇编 4.链接 动静态库链接的内容 动静态库链接的优缺点 5.总结记忆 前言 在前面我们学会使用vim对文件进行编辑,如果是C或者C程序,我们编辑好了内容…...

使用阿里云镜像创建一个Spring Boot项目
由于现在的idea在创建项目时已经不支持Java8版本了,如果我们还想用8版本,可以使用阿里云镜像创建。所以得改变原有的地址为:https://start.aliyun.com springboot版本选择2开头的任意版本的。 1.配置6个依赖 2.改变下载依赖地址 下载依赖默认…...

工智能基础知识总结--词嵌入之Word2Vec
词嵌入要解决什么问题 在自然语言系统中,词被看作最为基本的单元,如何将词进行向量化表示是一个很基本的问题,词嵌入(word embedding)就是把词映射为低维实数域向量的技术。 下面先介绍几种词的离散表示技术,然后总结其缺点,最后介绍词的分布式表示及其代表技术(word2v…...

redis stream restTemplate消息监听队列框架搭建
整体思路 1. pom增加redis依赖; 2. 消息监听器,实现StreamListener接口,处理消息到达逻辑; 3. 将消息订阅bean及监听器注册到配置中; 1. pom <?xml version"1.0" encoding"UTF-8"?> <…...

【期末不挂科-C++考前速过系列P1】大二C++第1次过程考核(3道简述题&7道代码题)【解析,注释】
前言 大家好吖,欢迎来到 YY 滴C复习系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《Lin…...

游戏开发中,你的游戏图片压缩格式使用ASTC了吗
文章目录 ASTC原理:使用要求 ASTC(Adaptive Scalable Texture Compression,自适应可伸缩纹理压缩)是一种高级的纹理压缩技术,由ARM公司开发并推广。它在图形处理领域中因其出色的压缩效率和灵活性而受到广泛关注。 AST…...

【PostgreSQL】数据查询-概述
PostgreSQL数据查询 概述 检索或从数据库中检索数据的命令的过程称为查询。在 SQL 中,SELECT 命令用于指定查询。该命令的一般语法是SELECT [WITH with_queries] SELECT select_list FROM table_expression [sort_specification]一种简单的查询形式为:…...

element input组件自动失去焦点问题解决
最近在 Vue3 ElementPlus 中,使用 el-input 组件时,如果设置了 v-model,那么在每次改变内容后后,input 会自动失去焦点,这样会导致用户无法输入多个字符。 一、问题原因 如上图所示,配置项的 Name 和 Cod…...

鸿蒙Harmony--状态管理器-@Observed装饰器和@ObjectLink装饰器详解
经历的越多,越喜欢简单的生活,干净的东西,清楚的感觉,有结果的事,和说到做到的人。把圈子变小,把语放缓,把心放宽,用心做好手边的事儿,该有的总会有的! 目录 一ÿ…...