vuejs计算属性computed & 监听属性watch

一、计算属性computed 1.1 什么是计算属性 computed是vue的计算属性,是根据依赖关系进行缓存的计算,只有在它的相关依赖发生改变时才会进行更新。 <template> <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> </template> <script> export default { name: "CT", data() { return { message: "Hello", }; }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split("").reverse().join(""); }, }, }; </script> 可以像绑定普通 property 一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。

三行命令搞定nnUNet v2训练及推理!

通过前面2小节的学习,我们配好了环境,准备了数据。现在开始你的训练之旅~~ 同 V1 一样,一行命令搞定你的数据预处理,训练和测试!! ​ step1: 一行命令数据预处理 使用命令: nnUNetv2_plan_and_preprocess 注意: v2 版本的命令,都是以 nnUNetv2开头 nnUNetv2_plan_and_preprocess -h 可查看使用帮助 nnUNetv2_plan_and_preprocess -d 131(你的数据ID) --verify_dataset_integrity 数据预处理好后,会放在 nnUNet_preprocessed>Datasetxxx_xxx里面 step2: 一行命令开始训练 使用 nnUNetv2_train 命令进行模型训练。命令的一般结构如下: nnUNetv2_train DATASET_NAME_OR_ID UNET_CONFIGURATION FOLD [其他选项,参见 -h] eg: nnUNetv2_train 131 3d_fullres 1 (表示使用131这个数据集,模型用3d_fullres,训练第一折) UNET_CONFIGURATION: 用于标识所需的 U-Net 配置(defaults: 2d, 3d_fullres, 3d_lowres, 3d_cascade_lowres)。DATASET_NAME_OR_ID: 指定应在其上训练的数据集,FOLD 则指定要训练的 5 折交叉验证中的哪一个折数,0-4表示单个折数,all和5表示5折一起训练。 请注意,并非所有 U-Net 配置都适用于所有数据集。在图像尺寸较小的数据集中,级联 U-Net(以及其中的3D低分辨率配置)会被省略,因为全分辨率 U-Net 的裁剪大小已经涵盖了输入图像的大部分内容。 nnU-Net会每50个epochs存储一次 checkpoint。如果需要继续之前的训练,请将训练命令中添加 --c 参数。 nnUNetv2_train 131 3d_fullres 1 --c 重要提示:如果您计划使用 nnUNetv2_find_best_configuration,请添加 --npz 标记。这会让 nnU-Net 在最终验证期间保存 softmax 输出。它们是必需的。导出的 softmax 预测非常大,因此可能占用大量磁盘空间,因此默认情况下不启用此功能。如果您最初没有使用 --npz 标记运行,但现在需要 softmax 预测,请使用以下命令重新运行验证:

ORB-SLAM3复现的详细过程——配置安装及ROS和脚本运行---Ubuntu20.04

ORB-SLAM3配置安装及ROS和脚本运行---Ubuntu20.04 1. 安装所需要的依赖和包2. 修改代码及文件内容2.1 CMakeLists.txt文件的修改2.2 单目可视化代码修改2.3 环境配置文件的修改2.4 源码的修改 3.ORB-SLAM3的编译3.1 构建 ORB-SLAM3 库3.2 生成ROS节点 4.ORB-SLAM3的运行4.1 非ROS环境下运行4.1.1 EuROC数据集4.1.2 TUM VI 数据集 4.2 ROS环境下运行 ORB-SLAM3代码下载地址:ORB-SLAM3源码下载 所有的操作都是在完成以下网址中的所有操作内容下进行的:Ubuntu系统安装之后首需要做的事情 本文是总结的比较完善和直接的过程。 其实在整个运行中也遇到了一些问题,也做了一些总结,记录在了文章 ORB-SLAM3复现过程中遇到的问题及解决办法中 建议是先以本文为主,有问题之后再去参考问题解决办法。 1. 安装所需要的依赖和包 在一键安装ROS后,只需要再安装Pangolin即可,其他所有的需要都已经存在。 依次执行以下命令即可: #依赖项 sudo apt-get install libglew-dev sudo apt-get install cmake sudo apt-get install libpython2.7-dev sudo apt-get install ffmpeg libavcodec-dev libavutil-dev libavformat-dev libswscale-dev libavdevice-dev sudo apt-get install libdc1394-22-dev libraw1394-dev sudo apt-get install libjpeg-dev libpng-dev libtiff5-dev libopenexr-dev #下载编译 git clone https://github.com/stevenlovegrove/Pangolin.git cd Pangolin mkdir build cd build cmake .

ORB-SLAM3复现过程中遇到的问题及解决办法

在复现过程中遇到的问题的解决过程 1. 版本检查1.1 Opencv版本的检测1.2 Eigen版本的检测1.3 查看Python版本1.4 其他 2. 编译过程中遇到的问题及解决办法2.1 ./build.sh遇到的问题2.2 ./build_ros.sh遇到的问题 因为环境比较干净,所以遇到的问题相对少一些,不过每一个问题都进行了完善的解决 我的环境是刚装完Ubuntu20.04之后,并进行了Ubuntu系统安装之后首需要做的事情的操作之后的一个环境。 1. 版本检查 因为ORB-SLAM3对环境的要求和ORB-SLAM2有一些不一样,有的版本过低是会导致错误的。 所以,在开始之前,先来检测一下自己环境中的库的版本。 注意:使用的是Ubuntu20.04 1.1 Opencv版本的检测 执行以下命令,可以发现版本为4.2.0 pkg-config --modversion opencv # 4.2.0 //或者 opencv_version # 4.2.0 1.2 Eigen版本的检测 执行以下命令: whereis eigen3 # 我的是在/usr/include/eigen3 gedit /usr/include/eigen3/Eigen/scr/Core/util/Macros.h 文件开头的几行如下所示,意味着我的Eigen版本为3.3.7 #ifndef EIGEN_MACROS_H #define EIGEN_MACROS_H #define EIGEN_WORLD_VERSION 3 #define EIGEN_MAJOR_VERSION 3 #define EIGEN_MINOR_VERSION 7 1.3 查看Python版本 执行以下命令: xiaoduan@fighter:~$ python3 --version Python 3.8.10 也可以在终端输入python接着连着按两下tab键,也能看到自己的python版本。 1.4 其他 在c++方面,我的是C++11。DBoW2 and g2o在项目文件中直接存在,无需手动安装,在编译的过程中会自动安装。Pangolin还没有安装。 2. 编译过程中遇到的问题及解决办法 2.

Vue3+TypeScript+Pinia初始化项目,vscode报错解决办法!

初始化项目后,vscode打开项目,如下图报错信息: tsconfig.json tsconfig.node.json vite.config.ts 解决办法: 将tsconfig.json和tsconfig.node.json两个文件中moduleResolution值做修改为node { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "node", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "references": [{ "path": "./tsconfig.node.json" }] } 这样之后大部分红线已经没了,但是tsconfig.json中allowImportingTsExtensions属性依然还是报错!!! 大概意思:TS5023 (TS) 未知的编译器选项“allowImportingTsExtensions”。 该选项用于控制是否允许在 import 语句中导入 .ts 文件扩展名,它的取值可以是 true 或 false。但是,从 TypeScript 3.

基于aarch64分析kernel源码 四:printk 内核打印

一、参考 Message logging with printk — The Linux Kernel documentation 如何获得正确的printk格式占位符 — The Linux Kernel documentation 使用printk记录消息 — The Linux Kernel documentation printk 内核打印 – 人人都懂物联网 (getiot.tech) 内核printk原理介绍 - 知乎 (zhihu.com) Linux kernel log与调试_内核log_hui_zh的博客-CSDN博客 linux内核日志的存储与读取 | QZJ (eathanq.github.io) 二、printk概述 printk 函数主要做两件事情: 将信息记录到 log 中;调用控制台驱动来将信息输出。 从上图可看出,其核心是一个叫做log buffer的循环缓冲区,printk作为生产者将消息存入该缓冲区,右边的log服务模块作为消费者可从log buffer中读取消息。这样设计有以下几个优点: 1、控制台和日志模块初始化前,内核的启动日志可以暂存到log buffer中。待它们初始化完成后,再输出相应信息。 2、在printk log输出太快,而log服务的处理速度不足时,防止log信息丢失。 3、将log输入模块和log输出模块解耦,增加设计的灵活性。 三、log buffer 在内核启动初期,系统内存布局和log buffer大小(cpu核心数等因素决定)不确定,导致无法动态分配内存。为了支持printk,内核通过全局变量方式定义一个log buffer(全局变量被定义在数据段中,会在内核镜像映射过程中被映射),其定义如下: // kernel/printk/printk.c /* record buffer */ #define LOG_ALIGN __alignof__(unsigned long) #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) #define LOG_BUF_LEN_MAX (u32)(1 << 31) static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); static char *log_buf = __log_buf; static u32 log_buf_len = __LOG_BUF_LEN; 当必要信息初始化完成后,在 start_kernel 函数中调用 setup_log_buf(0) 函数动态分配 log buffer。

C库字符串函数介绍

1、strstr() C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。 下面是 strstr() 函数的声明。 char *strstr(const char *haystack, const char *needle) 参数 haystack -- 要被检索的 C 字符串。needle -- 在 haystack 字符串内要搜索的小字符串。 返回值 该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。 返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。 需要注意的是haystack的长度要大于needle 示例1: 输出:str str2 str1 示例2: char str[]="1234xyz"; char *str1=strstr(str,"34"); cout 输出: 34xyz 2、char *和char[]的区别是什么 在C和C++中,char*和char[]都用于表示字符数组,但它们之间存在一些重要的区别: 存储:char*是一个指向字符的指针,它只存储了一个地址,这个地址通常指向一个字符串常量或者动态分配的内存。另一方面,char[]是一个真正的字符数组,它存储了一串字符。生命周期:char[]的内存是在栈上分配的,其生命周期与包含它的函数或代码块一致。当函数或代码块执行完毕,该内存将被自动释放。另一方面,char*可以指向动态分配的内存,其生命周期取决于程序员如何管理它。如果程序员忘记释放内存,可能会导致内存泄漏。字符串常量:当char*指向一个字符串常量时,例如char* s = "Hello";,实际上s只是一个指向字符串常量的指针。字符串常量是不可修改的,试图修改它会导致未定义行为。这种情况下,使用const char*更安全。另一方面,char[]可以创建一个可以修改的字符串。 下面是一些例子来说明这些区别: // char* example char* s1 = "

C语言文件操作入门指南

简介: C语言作为一种广泛应用于系统级编程和嵌入式开发的编程语言,其文件操作功能非常重要。本篇博客将介绍C语言中常用的文件操作函数,帮助读者初步掌握文件的读写、打开和关闭等基本操作。 1. 打开文件: C语言中使用函数fopen来打开文件。它接受两个参数:文件名和打开模式。 常见的打开模式有: "r"(只读打开), "w"(写入打开)、 "a"(追加打开)、 "rb"(二进制只读打开)、 "wb"(二进制写入打开)等。 例如: FILE* file = fopen("example.txt", "r"); 2. 关闭文件: 用完文件后,应及时关闭以释放资源。使用函数fclose来关闭文件。它接受一个参数:指向已打开文件的指针。 例如: fclose(file); 3. 读取文件内容: 使用函数fscanf或fgets来读取文件中的内容。fscanf以指定格式从文件中读取,并将读取结果赋值给指定变量。fgets一次读取一行字符,将其存储在指定的字符串变量中。 // 使用fscanf逐个读取文件内容 int num; fscanf(file, "%d", &num); // 使用fgets逐行读取文件内容 char buffer[255]; fgets(buffer, sizeof(buffer), file); 4. 写入文件内容: 使用函数fprintf或fputs来向文件中写入内容。fprintf以指定的格式将变量的值写入文件。而fputs则直接将字符串写入文件中。 // 使用fprintf写入内容 int num = 10; fprintf(file, "%d", num); // 使用fputs写入内容 char str[] = "Hello, World!"; fputs(str, file); 5. 检查文件是否结束: 文件结束标志EOF(End of File)用于判断文件是否读取到结尾。在读取文件内容时,可以通过检查返回值来判断是否读取到了文件末尾。 char buffer[255]; while (fgets(buffer, sizeof(buffer), file) !

Error:Java:无效的源发行版:14

问题描述:项目拉下来,跑的时候发现版本有问题。这个问题可好解决了,只需要看下面几个方面,然后让他们保持一致就OK了 step1:查看本地的jdk版本 打开cmd窗口,输入命令 java -version就可以查看到本地的jdk版本 step2:查看项目版本 step3:查看项目中模块的版本 如果这里的版本和step1中不一致,就把不一样的改成一样的,从项目的pom.xml文件里改,然后重新下载依赖就好了

解决: lsmod, lspci等command not found

使用下面命令安装好以后,lspci可以使用 sudo apt-get install procps pciutils 使用下面命令安装好以后,lsmod可以使用 sudo apt-get install kmod

将一个毫秒数值分别转换为天,时,分,秒

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body></body> <script> var d = new Date(); let a1970 = d.valueOf(); //下面是将一个毫秒数值分别转换为天,时,分,秒 a1970 = a1970 / 1000; //除以1000,将毫秒数转成秒数(1秒=1000毫秒) let sec = parseInt(a1970 % 60); //余60,得到秒数(1分钟=60秒) let min = parseInt(a1970 / 60) % 60; //除以60,余60,得到分钟数(1小时=60分钟) let hour = parseInt(a1970 / 3600) % 24; //除以3600,余24,得到小时数(1天=24小时) let day = parseInt(a1970 / (3600 * 24)); //除以86400,得到天数 document.write( "距离1970年1月1日午夜以来过去了: "

shell 循环、数组与函数

循环 一、shell 循环:for 1、语法 for 循环开始时,会对变量 i 进行赋值,并执行 do 和 done 之间的代码,在第一次循环后,对 i 再次赋值 2、循环测试 ip 连通性 测试 192.168.198.1 - 192.168.198.3 的连通性 -W1:等待1秒钟,无法 ping 通则放弃 for i in {1..3} do ip=192.168.198.$i ping -c1 -W1 $ip &> /dev/null if [ $? -eq 0 ] then echo "$ip" | tee -a ip.txt fi done 测试结果: 3、循环创建用户 要求: 用户使用参数形式,通过读取自定义用户名文件来创建用户; 如果用户没有输入用户名文件,提示用户输入; 如果用户输入的不是文件,提示用户更正; 用户存在,提示存在 ;用户不存在,则创建用户。 #!/bin/bash #用户初始化密码 password=123 #判断脚本是否有参数 if [ $# -eq 0 ] ; then echo "

Qemu虚拟arm开发板驱动开发详解(一)——驱动基本架构

此前在《WSL2下Ubuntu22.04使用Qemu搭建虚拟Vexpress-A9开发板》系列文章中,我们已建立好Linux最小系统的运行环境,并将其成功移植到了由Qemu模拟的arm32开发板上。接下来将介绍如何基于上述环境进行驱动开发。 本节主要带各位读者了解Linux内核驱动的基本架构,并在WSL的Ubuntu22.04子系统下实现基于x86操作系统的简易Linux驱动“HelloWorld”。 Linux驱动框架 #include <linux/module.h> //包含内核编程最常用的函数声明,如printk #include <linux/kernel.h> //包含模块编程相关的宏定义,如:MODULE_LICENSE /*init初始化函数在模块被插入进内核时调用,主要作用为驱动功能做好预备工作 被称为模块的入口函数 __init的作用 : 1. 一个宏,展开后为:__attribute__ ((__section__ (".init.text"))) 实际是gcc的一个特殊链接标记 2. 指示链接器将该函数放置在 .init.text区段 3. 在模块插入时方便内核从ko文件指定位置读取入口函数的指令到特定内存位置 */ int __init mydriver_init(void) { …………………… return 0; } /*exit退出函数在模块从内核中被移除时调用,主要作用做些init函数的反操作 被称为模块的出口函数 __exit的作用: 1.一个宏,展开后为:__attribute__ ((__section__ (".exit.text"))) 实际也是gcc的一个特殊链接标记 2.指示链接器将该函数放置在 .exit.text区段 3.在模块插入时方便内核从ko文件指定位置读取出口函数的指令到另一个特定内存位置 */ void __exit mydriver_exit(void) { …………………… } /* MODULE_LICENSE(字符串常量); 字符串常量内容为源码的许可证协议 可以是"GPL" "GPL v2" "GPL and additional rights" "Dual BSD/GPL" "Dual MIT/GPL" "Dual MPL/GPL"等, "GPL"最常用 其本质也是一个宏,宏体也是一个特殊链接标记,指示链接器在ko文件指定位置说明本模块源码遵循的许可证 在模块插入到内核时,内核会检查新模块的许可证是不是也遵循GPL协议,如果发现不遵循GPL,则在插入模块时打印抱怨信息: myhello:module license 'unspecified' taints kernel Disabling lock debugging due to kernel taint 也会导致新模块没法使用一些内核其它模块提供的高级功能 */ MODULE_LICENSE("

永磁同步电机矢量控制(三)——电流环 PI 参数整定(三)

往期相关文章: 永磁同步电机矢量控制(三)——电流环 PI 参数整定(一) 永磁同步电机矢量控制(三)——电流环 PI 参数整定(二) 文章目录 1、不考虑延迟时间的电流控制回路参数整定2、考虑延迟时间的电流控制回路参数整定3、考虑延迟时间,不同PI参数下的幅频特性曲线的对比 这节我们讲下考虑延迟时间的电流控制回路中,带宽的设计和PI参数的整定。 1、不考虑延迟时间的电流控制回路参数整定 图上是不考虑延迟时间的电流控制回路的框图,如果我们要设计电流环的带宽为w,那么根据上一节所讲,Kp Ki的参数就整定为 Kp = wL,Ki = WR;但是在实际的控制系统回路中是存在延迟的,实测的和设计的带宽相差是比较大的。那当我还想要设计电流环的带宽为w时,那么这时电流环的参数该如何整定呢? 2、考虑延迟时间的电流控制回路参数整定 再回到开始的问题,如果想要设计电流环的带宽为w,那么Kp Ki怎么整定呢? 先找β 如果要设计电流环的带宽为w,则 β = ω T d \beta=\omega T_{d} β=ωTd​ 根据β再算 α \alpha α 根据上式计算 α \alpha α; 最后求Kp Ki 3、考虑延迟时间,不同PI参数下的幅频特性曲线的对比 这里写了个matlab脚本例子: L = 0.00046; %电机相电感 R = 0.62; %电机相电阻 f = 400; %需要设计的电流环带宽 Td = 100e-6;%电流环的延迟时间 Kp = L*f*2*pi;%理想情况下没有延迟时间整定的Kp Ki = R*f*2*pi;%理想情况下没有延迟时间整定的Ki s=tf('s'); G1 = Kp + Ki/s; %PI控制器传函 G2 = 1/(L*s + R);%电机传函 Gc = feedback(G1*G2,1);%电流闭环系统 bode(Gc) %按理想不带延迟时间整定的PI参数,在理想不带延迟时间电流环中的伯德图 hold on Gc2 = feedback(G1*G2*exp(-Td*s),1); bode(Gc2) %按理想不带延迟时间整定的PI参数,在带延迟时间电流环中的伯德图 hold on b = f*2*pi*Td; a = b*(sqrt(sin(b)*sin(b)+1)-sin(b)); Kp = L*a/Td; Ki = R*a/Td; G1 = Kp + Ki/s; G2 = 1/(L*s + R); Gc3 = feedback(G1*G2*exp(-Td*s),1);%按带延迟时间整定的PI参数,在带延迟时间电流环中的伯德图 bode(Gc3) 从伯德图中可以看出:如果实际带延迟时间的电流环中,PI参数按理想的不带延迟时间整定时,其实际的电流环带宽会比设置的大很多,甚至达到2~3倍。而考虑延迟时间来整定的PI参数,和理想的需要设置的带宽相差不大。

Failed to connect to the remote extension host server(Error: WebSocket close with status code 1006)

问题截图 解决办法(第一种情况): 首先,检查远程服务器上的 /etc/ssh/sshd_config里,有没有允许端口转发:AllowTcpForwarding yes更改后,重启 sshd服务:systemctl restart sshd。然后,删除~/.vscode-server目录本地Vscode settings的user配置里,把remote.SSH.remoteServerListenOnSocket的勾去掉(因为remote配置那里这个remoteServerListenOnSocket是关掉的),Remote: Auto Forward Ports前面的勾确认是打开的。成功连接上以后,本地和远程服务器的remote.SSH.remoteServerListenOnSocket的勾会自动打开。总结:连接的双方配置应该是对称的。先要保证服务器那边sshd_config端口转发打开,然后设置上remoteServerListenOnSocket都关闭,Remote: Auto Forward Ports都打开。成功连接上以后,remoteServerListenOnSocket的勾会自动打开,两边趁着现在ssh连接成功可以改,就都手动关了,否则又会出现连不上的问题。因为连不上的时候,remote那边不让改,就两头堵了。 第二种情况:如果上面方法不行,那么就把远程服务器上的openssh更新一下,yum update openssh. -wget,curl一般不用更新。他们是远程服务器上用来下载一些东西的,如果remote ssh扩展的输出日志中显示Downloading complete,我们就知道,其实wget,curl是没事的,问题不出在这里。 最后发现的第三种情况 ssh连不上的时候,settings里remote那边的配置不让改。实在不行,我把C:\Users\用户名\AppData\Roaming\Code下的东西全删了,然后把本地user配置里,remote.SSH.remoteServerListenOnSocket的勾去掉,因为remote那边的remoteServerListenOnSocket的勾是去掉的,然后再连就好了。 最后,当VScode连接成功后,日志为如下所示:

在 Vue 2 中在对象嵌套多层级的情况下使用双向绑定时失效的原因和解决办法

原因 Vue 2 的双向绑定是基于对象的属性 getter 和 setter 实现的,而当对象嵌套多层级时,Vue 2 无法自动追踪到深层嵌套属性的变化。(这个跟watch监听是一样的,watch开启深度监听就可以监听到了) 在 Vue 2 中,当你创建一个响应式数据对象时,Vue 会使用 Object.defineProperty 或 Proxy(在支持的浏览器中)来劫持对象的属性访问,从而在访问或修改属性时触发相应的操作。 然而,这种劫持只会发生在对象的第一层属性上。当你在 Vue 2 中使用双向绑定时,Vue 只会劫持对象的顶层属性,而不会递归地劫持对象的深层嵌套属性。 这意味着,当你修改对象嵌套多层级的属性时,Vue 无法自动追踪到这些属性的变化,因为它没有劫持这些深层嵌套属性的访问和修改操作。 举个例子,假设你有一个对象 obj,其中包含嵌套的属性 obj.obj1.obj2。当你修改obj.obj1.obj2 的值时,Vue 无法自动追踪到这个变化,因为它只劫持了 obj、obj.obj1 这两个层级的属性,而没有劫持obj.obj1.obj2。 const obj = { obj1: { obj2: { value: '1' } } } 为了解决这个问题,Vue 2 提供了 $set 方法,它可以用来显式地告诉 Vue 响应式地更新嵌套对象的属性。通过使用 $set 方法,你可以通知 Vue 对象的属性发生了变化,从而让 Vue 正确地追踪到这个变化,并保持双向绑定的功能。 解决办法 总结来说,Vue 2 中对象嵌套多层级时双向绑定失效的底层原因是 Vue 只劫持了对象的顶层属性,而没有劫持深层嵌套属性的访问和修改操作。可以使用 this.$set 或Vue.set方法可以解决这个问题,让 Vue 正确地追踪到嵌套属性的变化。 Vue3对比 Vue 3的响应式系统对于深层级嵌套对象提供了更好的支持,可以智能地跟踪属性的变化,并保持双向绑定的正常工作,所以在Vue 3中,对象在嵌套多层级的情况下使用双向绑定不会失效。

柔性数组

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、柔性数组的特点二、柔性数组的使用三、柔性数组的优势 前言 也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。 C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。 例如: typedef struct st_type { int i; int a[0];//柔性数组成员 }type_a; 有些编译器会报错无法编译可以改成: typedef struct st_type { int i; int a[];//柔性数组成员 }type_a; 一、柔性数组的特点 结构中的柔性数组成员前面必须至少一个其他成员。 sizeof 返回的这种结构大小不包括柔性数组的内存。 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大 小,以适应柔性数组的预期大小。 例如: //code1 typedef struct st_type { int i; int a[0];//柔性数组成员 }type_a; printf("%d\n", sizeof(type_a));//输出的是4 二、柔性数组的使用 //代码1 int i = 0; type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int)); //业务处理 p->i = 100; for(i=0; i<100; i++) { p->a[i] = i; } free(p); 这样柔性数组成员a,相当于获得了100个整型元素的连续空间。 三、柔性数组的优势 上述的 type_a 结构也可以设计为:

js 数组去重的几种方法

在JavaScript中,有几种常用的方法可以对数组进行去重: 1. 使用Set 使用ES6中引入的Set数据结构,Set只会保留不重复的值,可以很方便地去除数组中的重复元素。 //去重一般数组 const array = [1, 2, 3, 3, 4, 5, 5]; const uniqueArray = [...new Set(array)]; console.log(uniqueArray); // [1, 2, 3, 4, 5] //去重一个JSON数组 const jsonArray = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 1, name: 'John' }, { id: 3, name: 'Bob' } ]; const uniqueJsonArray = Array.from(new Set(jsonArray.map(JSON.stringify))).map(JSON.parse); console.log(uniqueJsonArray); // Output: // [ // { id: 1, name: 'John' }, // { id: 2, name: 'Jane' }, // { id: 3, name: 'Bob' } // ] 2.

【ctf题目系列】ctfwiki pwn类型

categories: ctf ret2shellcode [root@ningan ret2shellcode]# ./ret2shellcode No system for you this time !!! 123 bye bye ~[root@ningan ret2shellcode]# checksec检查 [root@ningan ret2shellcode]# checksec ret2shellcode [!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2) [*] '/root/ctf/ctfwiki/ret2shellcode/ret2shellcode' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments 32位程序 NX disabled = 可以将shellcode放在数据段,即可执行 ida分析 int __cdecl main(int argc, const char **argv, const char **envp) { char s[100]; // [esp+1Ch] [ebp-64h] BYREF setvbuf(stdout, 0, 2, 0); setvbuf(stdin, 0, 1, 0); puts("