当前位置: 首页 > news >正文

【深度学习】ND4J-科学计算库

目录

简介

基础用法

基础信息

数组创建

打印数组

变更维度&堆叠

加减乘除

累加/最大/最小

转换操作

矩陈乘法

索引/迭代

深拷贝/引用传递/视图

引用传递

视图

深拷贝

其它


简介

ND4J主要是JVM的科学计算库,内置了很多计算方法,目的是以最低的RAM需求快速运行。主要特点是:

  • 一个多功能的n维数组对象。

  • 线性代数和信号处理函数。

  • 多平台功能,包括GPU。

    • 所有主要操作系统: win/linux/osx/android.

    • 架构: x86, arm, ppc.

Nd4j的主要特点是具有多功能的n维阵列接口INDArray。为了提高性能,Nd4j使用堆外内存来存储数据。INDArray不同于标准Java数组。

基础用法

基础信息

创建数值为0的N维数组

INDArray xx = Nd4j.zeros(10);
System.out.println(xx);//运行结果
[         0,         0,         0,         0,         0,         0,         0,         0,         0,         0]INDArray x = Nd4j.zeros(3, 4);
System.out.println(x);//运行结果
[[         0,         0,         0,         0], [         0,         0,         0,         0], [         0,         0,         0,         0]]

同理,也支持三维、四维等,可以通过以下方法进行维度信息的查看:

// 数组的轴数(维度)。
int dimensions = x.rank();// 数组的维数。每个维度的大小。
long[] shape = x.shape();// 元素的总数。
long length = x.length();// 数组元素的类型。 
DataType dt = x.dataType();

数组创建

要创建INDArray,可以使用ND4J类的静态工厂方法。

Nd4j.createFromArray函数通过重载,支持double、float、int、long类型,同时对各种类型最高支持四维。

double arr_2d[][]={{1.0,2.0,3.0},{4.0,5.0,6.0},{7.0,8.0,9.0}};
INDArray x_2d = Nd4j.createFromArray(arr_2d);double arr_1d[]={1.0,2.0,3.0};
INDArray  x_1d = Nd4j.createFromArray(arr_1d);

可以使用函数zerosones创建用0和1初始化的数组

可以使用rand函数建用随机值初始化的数组

创建的INDArray的默认数据类型是float,有些重载允许您设置数据类型

INDArray  x = Nd4j.zeros(5);
//运行结果
//[         0,         0,         0,         0,         0], FLOATint [] shape = {5};
x = Nd4j.zeros(DataType.DOUBLE, 5);
//运行结果
//[         0,         0,         0,         0,         0], DOUBLE// 对于更高的维度,可以提供形状数组。二维随机矩阵示例:
int[] shape = {4, 5};
INDArray x = Nd4j.rand(shape);//运行结果
[[    0.5669,    0.0576,    0.8701,    0.9598,    0.6470], [    0.2711,    0.8427,    0.2819,    0.6617,    0.5109], [    0.0602,    0.2674,    0.6586,    0.9939,    0.4781], [    0.4099,    0.9503,    0.2227,    0.4738,    0.3759]]

使用arange函数创建一个均匀空间值数组:

INDArray  x = Nd4j.arange(5);
// [         0,    1.0000,    2.0000,    3.0000,    4.0000]INDArray  x = Nd4j.arange(2, 7);
// [    2.0000,    3.0000,    4.0000,    5.0000,    6.0000]

linspace函数允许您指定生成的点数:

//开始数, 停止数, 个数.
INDArray  x = Nd4j.linspace(1, 10, 5); 
// [    1.0000,    3.2500,    5.5000,    7.7500,   10.0000]// 对函数进行多点评估。
import static org.nd4j.linalg.ops.transforms.Transforms.sin;
INDArray  x = Nd4j.linspace(0.0, Math.PI, 100, DataType.DOUBLE);
INDArray  y = sin(x);

打印数组

如上图的例子,INDArray支持Java的toString()方法,可以直接通过System.out.println打印除结果

变更维度&堆叠

可以通过reshap函数进行维度的变更

int [] shape = {4,3};
//2维数组
x = Nd4j.arange(12).reshape(shape);   
/*
[[         0,    1.0000,    2.0000], [    3.0000,    4.0000,    5.0000], [    6.0000,    7.0000,    8.0000], [    9.0000,   10.0000,   11.0000]]
*/

如果本身数据的数组不足以填满新的维度,则会报ND4JIllegalStateException异常

int [] shape = {4,3};
//2维数组
INDArray x = Nd4j.arange(11).reshape(shape);//运行结果
//org.nd4j.linalg.exception.ND4JIllegalStateException: New shape length doesn't match original length: [12] vs [11]. Original shape: [11] New Shape: [4, 3]

INDArray x = Nd4j.rand(3,4);
x.shape();
// [3, 4]INDArray x2 = x.ravel(); //转化成一列
x2.shape();
// [12]INDArray x3 = x.reshape(6,2).shape();
x3.shape();
//[6, 2]//注意x、x2和x3共享相同的数据。 
x2.putScalar(5, -1.0);System.out.println( x);
/*
[[    0.0270,    0.3799,    0.5576,    0.3086], [    0.2266,   -1.0000,    0.1107,    0.4895], [    0.8431,    0.6011,    0.2996,    0.7500]]
*/System.out.println( x2);
// [    0.0270,    0.3799,    0.5576,    0.3086,    0.2266,   -1.0000,    0.1107,    0.4895,    0.8431,    0.6011,    0.2996,    0.7500]System.out.println( x3);
/*        
[[    0.0270,    0.3799], [    0.5576,    0.3086], [    0.2266,   -1.0000], [    0.1107,    0.4895], [    0.8431,    0.6011], [    0.2996,    0.7500]]
*/

可以使用vstackhstack方法将数组堆叠在一起。

INDArray x = Nd4j.rand(2,2);
INDArray y = Nd4j.rand(2,2);x
/*
[[    0.1462,    0.5037], [    0.1418,    0.8645]]
*/y;
/*
[[    0.2305,    0.4798], [    0.9407,    0.9735]]
*/Nd4j.vstack(x, y);
/*
[[    0.1462,    0.5037], [    0.1418,    0.8645], [    0.2305,    0.4798], [    0.9407,    0.9735]]
*/Nd4j.hstack(x, y);
/*
[[    0.1462,    0.5037,    0.2305,    0.4798], [    0.1418,    0.8645,    0.9407,    0.9735]]
*/

加减乘除

使用INDArray方法对数组执行操作。

加法: arr.add(...), arr.addi(...)减法: arr.sub(...), arr.subi(...)乘法: arr.mul(...), arr.muli(...)除法 : arr.div(...), arr.divi(...)

对数组进行加减乘除操作,有两种类型

【1】in-place :在原有数组基础上变更,如add、sub

【2】复制:创建新的数组,将结果放在新数组中,如addi、subi

//复制
//返回一个新数组,并将标量添加到arr的每个元素。
arr_new = arr.add(scalar);  
//返回一个新数组,它是arr和其他arr元素级别的加法。  
arr_new = arr.add(other_arr); //In-place
arr_new = arr.addi(scalar); 
arr_new = arr.addi(other_arr);

in-place运算符可以方便地将操作链接在一起。尽可能使用(in-place)运算符来提高性能,因为

复制运算符有新的数组创建开销。

注意,执行加减乘除操作时,必须确保基础数据类型相同。

int [] shape = {5};
INDArray  x = Nd4j.zeros(shape, DataType.DOUBLE);
INDArray  x2 = Nd4j.zeros(shape, DataType.INT);
INDArray  x3 = x.add(x2);
// java.lang.IllegalArgumentException: Op.X 和 Op.Y must have the same data type, but got INT vs DOUBLE// 将x2转换为DOUBLE可以解决以下问题:
INDArray x3 = x.add(x2.castTo(DataType.DOUBLE));

累加/最大/最小

INDArray有实现累加/最值操作的方法,如 sum, min, max.

int [] shape = {2,3};
INDArray  x = Nd4j.rand(shape);
x;
x.sum();
x.min();
x.max();
/*
[[    0.8621,    0.9224,    0.8407], [    0.1504,    0.5489,    0.9584]]
4.2830
0.1504
0.9584
*/

提供维度参数以在指定维度上应用操作:

INDArray x = Nd4j.arange(12).reshape(3, 4);
/*
[[         0,    1.0000,    2.0000,    3.0000], [    4.0000,    5.0000,    6.0000,    7.0000], [    8.0000,    9.0000,   10.0000,   11.0000]]
*/        //每列的总和。
x.sum(0); 
//[   12.0000,   15.0000,   18.0000,   21.0000]//每行最小值
x.min(1); 
//[         0,    4.0000,    8.0000]//每行的累计和,
x.cumsum(1); 
/*
[[         0,    1.0000,    3.0000,    6.0000], [    4.0000,    9.0000,   15.0000,   22.0000], [    8.0000,   17.0000,   27.0000,   38.0000]]
*/

转换操作

Nd4j提供熟悉的数学函数,如sin、cos和exp,这些称为转换操作。结果作为INDArray返回。

import static org.nd4j.linalg.ops.transforms.Transforms.exp;
import static org.nd4j.linalg.ops.transforms.Transforms.sqrt;INDArray x = Nd4j.arange(3);
// [         0,    1.0000,    2.0000]
exp(x);
// [    1.0000,    2.7183,    7.3891]
sqrt(x);
// [         0,    1.0000,    1.4142]

矩陈乘法

INDArray也支持矩阵运算,如下:

INDArray x = Nd4j.arange(12).reshape(3, 4);
/*
[[         0,    1.0000,    2.0000,    3.0000], [    4.0000,    5.0000,    6.0000,    7.0000], [    8.0000,    9.0000,   10.0000,   11.0000]]
*/INDArray y = Nd4j.arange(12).reshape(4, 3);
/*
[[         0,    1.0000,    2.0000], [    3.0000,    4.0000,    5.0000], [    6.0000,    7.0000,    8.0000], [    9.0000,   10.0000,   11.0000]]
*/
// 矩阵乘积.
x.mmul(y);  
/*
[[   42.0000,   48.0000,   54.0000], [  114.0000,  136.0000,  158.0000], [  186.0000,  224.0000,  262.0000]]
*///点积
INDArray x = Nd4j.arange(12);
INDArray y = Nd4j.arange(12);
dot(x, y);  
//506.0000

索引/迭代

获取某个位置的数据

INDArray x = Nd4j.arange(12);
// [         0,    1.0000,    2.0000,    3.0000,    4.0000,    5.0000,    6.0000,    7.0000,    8.0000,    9.0000,   10.0000,   11.0000]
//单一元素访问。其他方法: getDouble, getInt, ...
float f = x.getFloat(3);  
// 3.0

转化为Java数组

//转换为Java数组。
float []  fArr = x.toFloatVector();
// [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0]

获取指定区间的数据

INDArray x2 = x.get(NDArrayIndex.interval(2, 6));
// [    2.0000,    3.0000,    4.0000,    5.0000]

在x的副本上:从开始到位置6(不包括),将每2个元素设置为-1.0 

//在x的副本上:从开始到位置6(不包括),将每2个元素设置为-1.0
INDArray y = x.dup();
y.get(NDArrayIndex.interval(0, 2, 6)).assign(-1.0);
//[   -1.0000,    1.0000,   -1.0000,    3.0000,   -1.0000,    5.0000,    6.0000,    7.0000,    8.0000,    9.0000,   10.0000,   11.0000]

y的反向副本

//y的反向副本。
INDArray y2 = Nd4j.reverse(y.dup());
//[   11.0000,   10.0000,    9.0000,    8.0000,    7.0000,    6.0000,    5.0000,   -1.0000,    3.0000,   -1.0000,    1.0000,   -1.0000]

对于多维数组,应该使用INDArray.get(NDArrayIndex...)。下面的示例演示如何遍历二维数组的行和列。注意,对于2D数组,我们可以使用getColumngetRow便利方法。

// 在2d数组的行和列上迭代。
int rows = 4;
int cols = 5;
int[] shape = {rows, cols};INDArray x = Nd4j.rand(shape);
/*
[[    0.2228,    0.2871,    0.3880,    0.7167,    0.9951], [    0.7181,    0.8106,    0.9062,    0.9291,    0.5115], [    0.5483,    0.7515,    0.3623,    0.7797,    0.5887], [    0.6822,    0.7785,    0.4456,    0.4231,    0.9157]]
*/for (int row=0; row<rows; row++) {INDArray y = x.get(NDArrayIndex.point(row), NDArrayIndex.all());}
/*
[    0.2228,    0.2871,    0.3880,    0.7167,    0.9951]
[    0.7181,    0.8106,    0.9062,    0.9291,    0.5115]
[    0.5483,    0.7515,    0.3623,    0.7797,    0.5887]
[    0.6822,    0.7785,    0.4456,    0.4231,    0.9157]
*/for (int col=0; col<cols; col++) {INDArray y = x.get(NDArrayIndex.all(), NDArrayIndex.point(col));}
/*
[    0.2228,    0.7181,    0.5483,    0.6822]
[    0.2871,    0.8106,    0.7515,    0.7785]
[    0.3880,    0.9062,    0.3623,    0.4456]
[    0.7167,    0.9291,    0.7797,    0.4231]
[    0.9951,    0.5115,    0.5887,    0.9157]
*/

深拷贝/引用传递/视图

引用传递

以下用法,仅仅只是指向x的指针,进行了引用传递,并未复制

INDArray x = Nd4j.rand(2,2);
//y和x指向同一个INDArray对象。
INDArray y = x; 

视图

一些函数将返回数组的视图,并未进行数组的复制

INDArray x = Nd4j.rand(3,4);
INDArray  x2 = x.ravel();
INDArray  x3 = x.reshape(6,2);// 修改 x, x2 和 x3
x2.putScalar(5, -1.0); x
/*
[[    0.8546,    0.1509,    0.0331,    0.1308], [    0.1753,   -1.0000,    0.2277,    0.1998], [    0.2741,    0.8257,    0.6946,    0.6851]]
*/x2
// [    0.8546,    0.1509,    0.0331,    0.1308,    0.1753,   -1.0000,    0.2277,    0.1998,    0.2741,    0.8257,    0.6946,    0.6851]x3
/*
[[    0.8546,    0.1509], [    0.0331,    0.1308], [    0.1753,   -1.0000], [    0.2277,    0.1998], [    0.2741,    0.8257], [    0.6946,    0.6851]]
*/

深拷贝

要复制数组,请使用dup方法。这将为您提供一个包含新数据的新数组。

INDArray x = Nd4j.rand(3,4);
INDArray  x2 = x.ravel().dup();//现在只改变x2。
x2.putScalar(5, -1.0); 
x
/*
[[    0.1604,    0.0322,    0.8910,    0.4604], [    0.7724,    0.1267,    0.1617,    0.7586], [    0.6117,    0.5385,    0.1251,    0.6886]]
*/x2
// [    0.1604,    0.0322,    0.8910,    0.4604,    0.7724,   -1.0000,    0.1617,    0.7586,    0.6117,    0.5385,    0.1251,    0.6886]

其它

ND4J还有很多科学计算函数,具体可以查看文档

nd4j-api 1.0.0-M2.1 javadoc (org.nd4j)

相关文章:

【深度学习】ND4J-科学计算库

目录 简介 基础用法 基础信息 数组创建 打印数组 变更维度&堆叠 加减乘除 累加/最大/最小 转换操作 矩陈乘法 索引/迭代 深拷贝/引用传递/视图 引用传递 视图 深拷贝 其它 简介 ND4J主要是JVM的科学计算库&#xff0c;内置了很多计算方法&#xff0c;目的…...

2024-01-29 ubuntu 用脚本设置安装交叉编译工具链路径方法,设置PATH环境变量

一、设置PATH环境变量的方法,建议用~/.bash_profile的方法&#xff0c;不然在ssh登录的时候可能没有设置PATH. 二、下面的完整的脚本&#xff0c;里面的echo "export PATH$build_toolchain_path:\$PATH" >> $HOME/.bashrc 就是把交叉编译路径写写到.bashrc设置…...

今年春节很多年轻人选择不买战袍,减少年货置办,「极简过年」,如何看待此现象?

​近年来&#xff0c;春节期间出现了一种新的现象&#xff0c;越来越多的年轻人选择不买战袍&#xff0c;减少年货置办&#xff0c;采用“极简过年”的方式度过春节。对于这一现象&#xff0c;不同人有不同的看法。 首先&#xff0c;这种极简过年的方式符合当前社会的一些价值观…...

C语言·贪吃蛇游戏(下)

上节我们将要完成贪吃蛇游戏所需的前置知识都学完了&#xff0c;那么这节我们就开始动手写代码了 1. 程序规划 首先我们应该规划好我们的代码文件&#xff0c;设置3个文件&#xff1a;snack.h 用来声明游戏中实现各种功能的函数&#xff0c;snack.c 用来实现函数&#xff0c;t…...

Flask 入门2:路由

1. 前言 在上一节中&#xff0c;我们使用到了静态路由&#xff0c;即一个路由规则对应一个 URL。而在实际应用中&#xff0c;更多使用的则是动态路由&#xff0c;它的 URL是可变的。 2. 定义一个很常见的路由地址 app.route(/user/<username>) def user(username):ret…...

【C++】 C++入门— 基于范围的 for 循环

C 基于范围的for循环1 使用样例2 使用条件3 完善措施 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 基于范围的for循环 1 使用样例 使用for循环遍历数组&#xff0c;我们通常这么写&#xff1a; …...

C++——析构函数

C——析构函数 什么是析构函数 析构函数是C中的一个特殊的成员函数&#xff0c;它在对象生命周期结束时被自动调用&#xff0c;用于执行对象销毁前的清理工作。析构函数特别重要&#xff0c;尤其是在涉及动态分配的资源&#xff08;如内存、文件句柄、网络连接等&#xff09;…...

Vue3学习记录(二)--- 组合式API之计算属性和侦听器

一、计算属性 1、简介 ​ 计算属性computed()&#xff0c;用于根据依赖的响应式变量的变化&#xff0c;进行自动的计算&#xff0c;并返回计算后的结果。当依赖的响应式变量发生变化时&#xff0c;computed()会自动进行重新计算&#xff0c;并返回最新的计算结果。如果依赖的…...

react-virtualized实现行元素不等高的虚拟列表滚动

前言&#xff1a; 当一个页面中需要接受接口返回的全部数据进行页面渲染时间&#xff0c;如果数据量比较庞大&#xff0c;前端在渲染dom的过程中需要花费时间&#xff0c;造成页面经常出现卡顿现象。 需求&#xff1a;通过虚拟加载&#xff0c;优化页面渲染速度 优点&#xff1…...

Linux系统各目录作用

/etc文件系统 /etc 目录包含各种系统配置文件&#xff0c;下面说明其中的一些。其他的你应该知道它们属于哪个程序&#xff0c;并阅读该程序的m a n页。许多网络配置文件也在/etc 中。 1. /etc/rc或/etc/rc.d或/etc/rc?.d 启动、或改变运行级时运行的脚本或脚本的目录。 2. /…...

嵌入式系统学习(一)

嵌入式现状&#xff08;UP经历&#xff09;&#xff1a; 大厂的招聘要求&#xff1a; 技术栈总结&#xff1a; 产品拆解网站&#xff1a; 52audio 方案查询网站iotku,我爱方案网&#xff0c; 主要元器件类型&#xff1a;...

重写Sylar基于协程的服务器(3、协程模块的设计)

重写Sylar基于协程的服务器&#xff08;3、协程模块的设计&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器&#xff08;1、日志模…...

Linux之系统安全与应用续章

目录 一. PAM认证 1.2 初识PAM 1.2.1 PAM及其作用 1.2.2 PAM认证原理 1.2.3 PAM认证的构成 1.2.4 PAM 认证类型 1.2.5 PAM 控制类型 二. limit 三. GRUB加密 /etc/grub.d目录 四. 暴力破解密码 五. 网络扫描--NMAP 六. 总结 一. PAM认证 1.2 初识PAM PAM是Linux系…...

《HTML 简易速速上手小册》第7章:HTML 多媒体与嵌入内容(2024 最新版)

文章目录 7.1 在HTML中嵌入视频和音频7.1.1 基础知识7.1.2 案例 1&#xff1a;嵌入视频文件7.1.3 案例 2&#xff1a;嵌入音频文件7.1.4 案例 3&#xff1a;创建一个视频和音频混合的播放列表 7.2 使用 <iframe> 嵌入外部内容7.2.1 基础知识7.2.2 案例 1&#xff1a;嵌入…...

【CSS】移动端适配

移动端适配怎么做&#xff1f; 适配的目的是在屏幕大小不同的终端设备拥有统一的界面&#xff0c;让拥有更大屏幕的终端展示更多的内容。 meta viewport (视口) 移动端初始视口的大小默认是980px&#xff0c;因为世界上绝大多数PC网页的版心宽度为980px &#xff0c;如果网页…...

DFS剪枝算法经典题目-挑选

4954. 挑选 - AcWing题库 给定一个包含 n 个正整数 a1,a2,…,an的集合。 集合中可能存在数值相同的元素。 请你从集合中挑选一些元素&#xff0c;要求同时满足以下所有条件&#xff1a; 被选中元素不少于 2 个。所有被选中元素之和不小于 l 且不大于 r。所有被选中元素之中最大…...

考研经验总结——考试期间

文章目录 一、订房二、看考场三、休息四、考前带宾馆的书五、安全 一、订房 我刚刚看了看&#xff0c;是9.10号订的酒店。你们可以提前向学长学姐打听你的考场在哪个学校&#xff08;徐州的考生&#xff0c;考省外的学校是在矿大考试&#xff0c;考省内的学校是在江师大&#…...

vue3 源码解析(6)— lifecycle 生命周期的实现

前言 对于 vue3 的生命周期&#xff0c;我们经常性会去疑问&#xff0c;生命周期有哪些呢&#xff0c;它是怎么去实现的&#xff0c; 又是什么时候调用的。 vue3 生命周期有哪些 下面这个表格列出了所有选项式api生命周期钩子和组合式api生命周期钩子&#xff0c;以及他们的…...

three.js CSS2DRenderer、CSS2DObject渲染HTML标签

有空的老铁关注一下我的抖音&#xff1a; 效果&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red;position: relative;"><…...

SECS/GEM300和半导体e84控制器

SECS&#xff08;SEMI EQUIPMENT COMMUNICATIONS STANDARD 2&#xff09;半导体设备通讯标准 GEM&#xff08;Generic Equipment Model&#xff09;定义了Fab中各个场景下设备行为及其所使用SECS消息。 GEM300也称为300mm标准&#xff0c;FAB是12寸设备的处理作业规范。主要包…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...