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

Java从入门到精通 - 数组

数组

此笔记参考黑马教程,仅学习使用,如有侵权,联系必删

文章目录

  • 数组
    • 1. 认识数组
    • 2. 数组的定义和访问
      • 2.1 静态初始化数组
        • 2.1.1 数组的访问
          • 2.1.1 定义
          • 代码实现
          • 总结
        • 2.1.2 数组的遍历
          • 2.1.2.1 定义
          • 代码演示
          • 总结
        • 案例
          • 代码实现
      • 2.2 动态初始化数组
        • 2.2.1 定义
        • 2.2.2 动态初始化数组元素默认值规则
        • 代码实现
        • 总结
        • 案例
          • 代码实现
    • 3. 数组在计算机中的执行原理
      • 3.1 数组的执行原理,Java 程序的执行原理
        • 3.1.1 Java 内存分配介绍
        • 3.1.2 方法区
        • 3.1.3 栈
        • 3.1.4 堆
        • 3.1.5 数组在计算机中的执行原理
        • 总结
      • 3.2 多个变量指向同一个数组的问题
        • 3.2.1 使用数组时常见的一个问题
        • 代码实现
        • 总结
    • 专项训练:数组常见案例
      • 数组求最值
        • 分析
        • 代码实现
        • 总结
      • 数组反转
        • 需求 - 分析
        • 代码实现
        • 总结
      • 随机排名
        • 代码实现
        • 总结
    • 补充知识:Debug 工具的使用
    • 总结

1. 认识数组

  • 数组就是一个容器,用来存储一批同种类型的数据

  • 例子:

// 20, 10, 80, 60, 90
int[] arr = {20, 10, 80, 60, 90};// 张三, 李四, 王五
String[] names = {"张三", "李四", "王五"};

Java 中有变量,为什么还要用数组?

  • eg:在一组名单中随机点名的话,根据以往方法可能要定义几十上百个变量,会使得代码繁琐、实现需求复杂。而用数组的话代码简洁、逻辑清晰

  • 结论:遇到批量数据的存储和操作时,数组比变量更合适


2. 数组的定义和访问

2.1 静态初始化数组

  • 定义数组的时候直接给数组赋值

静态初始化数组的格式:

// 完整格式
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...};
int[] ages = new int[]{12, 24, 36};
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};
// 简化格式
数据类型[] 数组名 = {元素1, 元素2, 元素3, ...};
int[] ages = {12, 24, 36};

注意:

  • 数据类型[] 数组名“ 也可以写成 ”数据类型 数组名[]

  • 什么类型的数组只能存放什么类型的数据

  • 数组在计算机中的基本原理

    • 在计算机遇到代码之后,现在内存中开辟一块变量空间,暂时先不装东西。元素部分又开辟一个区域,每个元素各分为一块来存储数据,而这块区域是有自己的一个地址的,每个元素都有自己的编号(索引),然后将这个地址交给数组变量来存储

注意:数组变量名中存储的是数组在内存中的地址,数组是一种引用数据类型

  • 代码演示
package e_ArrayApp;public class a_ArrayDemo1 {public static void main(String[] args) {// 目标:掌握数组的定义方式一:静态初始化数组// 1. 数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...};int[] ages = new int[]{12, 24, 36};double[] scores = new double[]{89.9, 99.5, 59.5, 88};System.out.println(ages);System.out.println(scores);// 2. 简化写法// 数据类型[] 数组名 = {元素1, 元素2, 元素3, ...};int[] ages2 = {12, 24, 36};double[] scores2 = {89.9, 99.5, 59.5, 88};// 3. 数据类型[] 数组名 也可以写成 数据类型 数组名[]int ages3[] = {12, 24, 36};double scores3[] = {89.9, 99.5, 59.5, 88};}
}
  • 总结
  1. 数组的静态初始化的写法和特点是什么样的?

  1. 定义数组我们说了哪几个注意点?
  • 什么类型的数组必须存放什么类型的数据
  • 数据类型[] 数组名 也可以写成 数据类型 数组名[]
  1. 数组是属于什么类型,数组变量名中存储的是什么?
  • 引用数据类型,存储的数组在内存中的地址信息

2.1.1 数组的访问
2.1.1 定义
数组名[索引]

  • 数组的长度属性:length
// 获取数组的长度(就是数组元素的个数)
System.out.println(arr.length);
  • 数组的最大索引怎么表示?
数组名.length - 1 // 前提:元素个数大于0
代码实现
package e_ArrayApp;public class b_ArrayDemo {public static void main(String[] args) {// 目标:掌握数组的访问int[] arr = {12, 24, 36};// 1. 访问数组的全部数据System.out.println(arr[0]); // 12System.out.println(arr[1]); // 24System.out.println(arr[2]); // 36// 2. 修改数组中的数据arr[0] = 66;arr[2] = 100;System.out.println(arr[0]); // 66System.out.println(arr[1]); // 24System.out.println(arr[2]); // 100// 3. 访问数组的元素个数:数组名.lengthSystem.out.println(arr.length); // 3// 技巧:获取数组的最大索引:arr.length - 1(前提是数组中存在数据)System.out.println(arr.length - 1); // 2}
}
总结
  1. 如何访问数组的元素?
数组名[索引]
  1. 如何访问数组的长度?
  • 数组名称.length
  1. 数组的最大索引是多少?
数组名.length - 1 // 前提:元素个数大于0
  1. 如果访问数组时,使用的索引超过了数组的最大索引会出什么问题?
  • 执行程序时会出 bug,出现一个索引越界的异常提示

2.1.2 数组的遍历
2.1.2.1 定义
  • 遍历:就是一个一个数据的访问
  • 数组遍历:就是把数组的每个数据都取一遍出来

快速方法:

  • 数组名.fori + Tab
代码演示
package e_arrayapp;public class c_ArrayDemo3 {public static void main(String[] args) {// 目标:掌握数组的遍历int[] ages = {12, 24, 36};// System.out.println(ages[0]); // 12// System.out.println(ages[1]); // 24// System.out.println(ages[2]); // 36for (int i = 0; i < ages.length; i++) {// i = 0 1 2System.out.println(ages[i]); // 12 24 36}}
}
总结
  1. 什么是遍历?
  • 一个一个的访问一遍容器中的数据
  1. 如何遍历数组?
int[] ages = {20, 30, 40, 50};
for (int i = 0; i < ages.length; i++) {// i = 0 1 2System.out.println(ages[i]); // 12 24 36
}

案例

需求:

  • 某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额
  • 分析:
  1. 把这5个数据拿到程序中去 —> 使用数组
int[] money = {16, 26, 36, 6, 100};
  1. 遍历数组中的每一个数据,然后在外面定义求和变量把他们累加起来
代码实现
package e_arrayapp;public class d_ArrayTest4 {public static void main(String[] args) {// 目标:完成对数据的元素求和// 1. 定义一个数组存储5名员工的销售额int[] money = { 16, 26, 36, 6, 100 };// 3. 定义一个变量用于累加求和int count = 0;// 2. 遍历这个数组中的每个数据for (int i = 0; i < money.length; i++) {// i = 0 1 2 3 4count += money[i];}System.out.println("员工的销售额:" + count); // 184}
}

2.2 动态初始化数组

2.2.1 定义

数组的动态初始化:

  • 定义数组时先不存入具体的元素值,只确定数组存储的数据类型和数组的长度

数组的动态初始化格式:

数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
// 后赋值
arr[0] = 10;
System.out.println(arr[0]); // 10

  • 在内存中分配一个变量空间,在这个变量里面存储的还是数组对象的地址,这个数组对象里面,一开始会存一些所谓的默认值,后期再往这个里面进行赋值

注意:

  • 静态初始化和动态初始化数组的写法是独立的,不可以混用
2.2.2 动态初始化数组元素默认值规则
数据类型明细默认值
基本类型byte、short、char、int、long0
float、double0.0
booleanfalse
引用类型类、接口、数组、Stringnull
代码实现
package e_arrayapp;public class e_ArrayDemo5 {public static void main(String[] args) {// 目标:掌握定义数组的方式二:动态初始化数组// 1. 数据类型[] 数组名 = new 数据类型[长度];int[] ages = new int[3]; // ages = [0, 0, 0]System.out.println(ages[0]); // 0System.out.println(ages[1]); // 0System.out.println(ages[2]); // 0ages[0] = 12;ages[1] = 18;ages[2] = 32;System.out.println(ages[0]); // 12System.out.println(ages[1]); // 18System.out.println(ages[2]); // 32System.out.println("------------------------");char[] chars = new char[3]; // [0, 0, 0]System.out.println((int) chars[0]); // 0System.out.println((int) chars[2]); // 0double[] scores = new double[80];System.out.println(scores[0]); // 0.0System.out.println(scores[79]); // 0.0boolean[] flags = new boolean[100];System.out.println(flags[0]); // falseSystem.out.println(flags[99]); // falseString[] names = new String[80];System.out.println(names[0]); // nullSystem.out.println(names[79]); // null}
}
总结
  1. 动态数组的写法是什么样的?有什么特点?
数据类型[] 数组名 = new 数据类型[长度];
int[] ages = new int[4];
  1. 动态初始化数组后元素的默认值是什么样的?
  • byte、short、int、char、long 类型数组的元素默认值都是0
  • float、double 类型数组元素的默认值都是0.0
  • boolean 类型数组的元素默认值是 false,String 类型数组的元素的默认值是 null
  1. 两种数组定义的方法各自适合什么业务场景?
  • 动态初始化:适合开始不确定具体元素值,只知道元素个数的业务场景
  • 静态初始化:适合一开始就知道要存入哪些元素值的业务场景

案例

需求:

  • 某歌唱比赛,需要开发一个系统:可以录入6名评委的打分,录入完毕后立即输出平均分做为选手得分
  • 分析:
  1. 6名评委的打分是后期录入的,一开始不知道具体的分数,因此定义一个动态初始化的数组存分数
double[] scores = new double[6];
  1. 遍历数组中的每个位置,每次提示用户录入一个评委的分数,并存入数组对应的位置
  2. 遍历数组中的每一个元素进行求和最终算出平均分打印出来即可
代码实现
package e_arrayapp;import java.util.Scanner;public class f_ArrayTest6 {public static void main(String[] args) {// 目标:完成评委打分的案例// 1. 定义一个动态初始化的数组,负责存储6个评委的打分double[] scores = new double[6];Scanner sc = new Scanner(System.in);// 2. 遍历数组中的每个位置,录入评委的分数,存入数组中去for (int i = 0; i < scores.length; i++) {// i = 0 1 2 3 4 5 6System.out.println("请您输入当前第" + (i + 1) + "评委的分数");double score = sc.nextDouble();scores[i] = score;}// 3. 遍历数组中的每个元素进行求和double sum = 0;for (int i = 0; i < scores.length; i++) {sum += scores[i];}System.out.println("选手最终得分是:" + sum / scores.length);}
}

3. 数组在计算机中的执行原理

3.1 数组的执行原理,Java 程序的执行原理

前面我们知道,程序都是在计算机中的内存中执行的,那么 Java 程序编译后会产生一个 class 文件,然后这个 class 文件是提取到内存中正在运行的虚拟机里面去执行的。那么 Java 为了便于虚拟机执行这个 Java 程序,它将虚拟机中的这块内存区域进行了划分

3.1.1 Java 内存分配介绍
  • 方法区
  • 本地方法栈
  • 程序计数器
3.1.2 方法区
  • 定义:放我们编译以后的 class 文件的,也就是字节码文件

3.1.3 栈
  • 定义:方法运行时所进入的内存,由于变量是在方法里面的,所以变量也在这块区域里

3.1.4 堆
  • 定义:堆里面放的都是 new 出来的东西,它会在这块堆内存中开辟空间并产生地址,比如之前用的数组就是放在队里面的

ps:堆和栈在数据结构中应用广泛,具体可见 数据结构与算法

3.1.5 数组在计算机中的执行原理

把程序的 class 文件提取到方法区里面来,这里面会有一个 main 方法。接着它会把这个 main 方法加载到我们的栈里面来执行,接着它就会正式执行 main 方法的第一行代码,代码中基本类型变量就会在栈里面开辟空间。如果执行创建数组,就会先在栈里面开辟一个变量空间,一开始变量里面并没有存数据,紧接着执行等号右边的代码(new 一个数组对象),在堆内存中开辟一块空间,这块空间会分成 n 块等分的区域每个元素也有自己的索引,并且也会有一个地址,然后把这个地址赋值给左边的这个变量,再由变量指向这个数组对象

总结
  1. 运行一个 Java 程序,主要看 JVM 中包含的哪几部分内存区域?
  • 方法区
  • 栈内存
  • 堆内存
  1. 简单说说 int a = 20; int[] arr = new int[3] 这两行代码的执行原理?
  • a 是变量,直接放在栈中,a 变量存储的数据就是20这个值
  • new int[3] 是创建一个数组对象,会在堆内存中开辟区域存储3个整数
  • arr 是变量,在栈中,arr 中存储的是数组对象在堆内存中的地址值

3.2 多个变量指向同一个数组的问题

3.2.1 使用数组时常见的一个问题
  • 如果某个数组变量存储的地址是 null,那么该变量将不再指向任何数组对象

arr2 = null; // 把null赋值给arr2System.out.println(arr2); // nullSystem.out.println(arr2[0]); // 会出异常
System.out.println(arr2.length); // 会出异常
代码实现
package f_memory;public class b_ArrayDemo2 {public static void main(String[] args) {// 目标:认识多个变量指向同一个数组对象的形式,并掌握其注意事项int[] arr1 = {11, 22, 33};// 把int类型的数组变量arr1赋值给int类型的数组变量arr2int[] arr2 = arr1;System.out.println(arr1); // [I@5caf905dSystem.out.println(arr2); // [I@5caf905darr2[1] = 99;System.out.println(arr1[1]); // 99arr2 = null; // 拿到的数组变量中存储的值是nullSystem.out.println(arr2);// System.out.println(arr2[0]);System.out.println(arr2.length);}
}
总结
  1. 多个数组变量,指向同一个数组对象的原因是什么?需要注意什么?
  • 多个数组变量中存储的是同一个数组对象的地址
  • 多个变量修改的都是同一个数组对象中的数据
  1. 如果某个数组变量中存储的 null,代表什么意思?需要注意什么?
  • 代表这个数组变量没有指向数组对象
  • 可以输出这个变量,但不能用这个数组变量去访问数据或者访问数组长度,会报空指针异常:NullPointerException

专项训练:数组常见案例

数组求最值

分析

实现步骤:

  • 把数据拿到程序中去,用数组装起来
int[] socres = {15, 9000, 10000, 20000, 9500, -5};
  • 定义一个变量用于记录最终的最大值
int[] max = socres[0]; // 建议存储数组的第一个元素值作为参照 
  • 从第二个位置开始:遍历数组的数据,如果遍历的当前数据大于 max 变量存储的数据,则替换变量存储的数据为当前数据
  • 循环结束后输出 max 变量即可
代码实现
package g_demo;public class a_Test1 {public static void main(String[] args) {// 目标:掌握数组元素求最值// 1. 把数据拿到程序中来,用数组装起来int[] scores = {15, 9000, 10000, 20000, 9500, -5};// 2. 定义一个变量用于最终记住最大值int max = scores[0];// 3. 从数组的第二个位置开始遍历for (int i = 0; i < scores.length; i++) {// i = 1 2 3 4 5// 判断一个当前遍历的这个数据,是否大于最大值变量max存储的数据,如果大于当前遍历的数据需要赋值给maxif (scores[i] > max) {max = scores[i];}}System.out.println("最大数据是:" + max); // 20000}
}
总结
  1. 求数组中的元素最大值,我们是如何实现的?
  • 把数据拿到程序中去,用数组装起来
  • 定义一个变量 max 用于记录最大值,max 变量默认存储了第一个元素值作为参照物
  • 从第二个位置开始遍历数组的数据,如果当前元素大于变量存储的数据,则替换变量存储的值为该元素
  • 循环结束后输出 max 变量即可

数组反转

需求 - 分析

需求:

  • 某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转
    [10, 20, 30, 40, 50] 反转后 [50, 40, 30, 20, 10]

分析:

  • 数组的反转操作实际上就是:依次前后交换数据即可实现

代码实现
package g_demo;public class b_Test2 {public static void main(String[] args) {// 目标:完成数组反转// 1. 准备一个数组int[] arr = {10, 20, 30, 40, 50};// 2. 定义一个循环,设计2个变量,一个在前,一个在后for (int i = 0, j = arr.length - 1; i < j; i++, j--) {// arr[i]   arr[j]// 交换// 1. 定义一个临时变量记住后一个位置处的值int temp = arr[j];// 2. 把前一个位置处的值赋值给后一个位置arr[j] = arr[i];// 3. 把临时变量中记住的后一个位置处的值赋值给前一个位置arr[i] = temp;}// 3. 遍历数组中的每个数据,看是否反转成功了for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 50 40 30 20 10 }}
}
总结
  1. 我们如何完成数组的反转的?
  • 使用 for 循环,控制让数组的前后位置的元素,依次交换
  1. 数组如何实现前后元素交换的?
  • 定义一个临时变量记住后一个位置处的元素值
  • 再把前一个位置处的元素,赋值给后一个位置处
  • 最后把临时变量记住的后一个位置的值赋值给前一个位置处

随机排名

需求:

  • 某公司的开发部门有5名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报。请依次录入5名员工的工号,然后展示出一组随机的排名顺序

测试用例:[22, 33, 35, 13, 88] —> [13, 35, 88, 33, 22]

分析:

  • 在程序中录入5名员工的工号存储起来 —> 使用动态初始化数组的方式
  • 依次遍历数组中的每个数据
  • 每遍历到一个数据,都随机一个索引值出来,让当前数据与该索引位置处的数据进行交换
代码实现
package g_demo;import java.util.Random;
import java.util.Scanner;public class c_Test3 {public static void main(String[] args) {// 目标:完成随机排名// 1. 定义一个动态初始化的数组用于存储5名员工的工号int[] codes = new int[5];// [0, 0, 0, 0, 0]//  0  1  2  3  4// 2. 提示用户录入5名员工的工号Scanner sc = new Scanner(System.in);for (int i = 0; i < codes.length; i++) {// i = 0 1 2 3 4System.out.println("请您输入当前第" + (i + 1) + "员工的工号");int code = sc.nextInt();codes[i] = code;}// 3. 打乱数组中的元素排序Random r = new Random();for (int i = 0; i < codes.length; i++) {// codes[i]// 每遍历到一个数据,都随机一个数组索引范围内的值,然后让当前遍历的数据与索引位置处的值交换int index = r.nextInt(codes.length); // 0 - 4// 定义一个临时变量记住index位置处的值int temp = codes[index];// 把i位置处的值赋值给index位置处codes[index] = codes[i];// 把index位置原来的值赋值给i位置处codes[i] = temp;}// 4. 遍历数组中的工号输出即可for (int i = 0; i < codes.length; i++) {System.out.print(codes[i] + " ");}}
}
总结
  1. 我们是如何实现随即排名的?
  • 定义一个动态初始化的数组用于录入员工的工号
  • 遍历数组中的每个元素
  • 每遍历到一个数据,都随机一个索引值出来,让当前数据与索引位置出的数据进行交换

补充知识:Debug 工具的使用

  • IDEA(大部分 IDE 都有)自带的断点调试工具,可以控制代码从断点一行一行的执行,然后详细观看程序执行的情况

DEBUG 工具基本使用步骤

  1. 在需要控制的代码左侧,点击一下,形成断点
  2. 选择使用 DEBUG 方式启动程序,启动后程序会在断点暂停
  3. 控制代码一行一行的往下执行

断点:

用 Debug:

点击按钮,实现不同效果:


总结


相关文章:

Java从入门到精通 - 数组

数组 此笔记参考黑马教程&#xff0c;仅学习使用&#xff0c;如有侵权&#xff0c;联系必删 文章目录 数组1. 认识数组2. 数组的定义和访问2.1 静态初始化数组2.1.1 数组的访问2.1.1 定义代码实现总结 2.1.2 数组的遍历2.1.2.1 定义代码演示总结 案例代码实现 2.2 动态初始化…...

MySql事务索引

索引 1.使用 创建主键约束&#xff08;PRIMARY KEY&#xff09;、唯一约束&#xff08;UNIQUE&#xff09;、外键约束&#xff08;FOREIGN KEY&#xff09;时&#xff0c;会自动创建 对应列的索引。 2.创建索引&#xff08;普通索引&#xff09; 事务&#xff1a;要么全部…...

八股文-js篇

八股文-js篇 1. 延迟执行js的方式2. js的数据类型3. null 和 undefined的区别4. 和 的区别5. js微任务和宏任务6. js作用域7. js对象9. JS作用域this指向原型8. js判断数组9. slice作用、splice是否会改变原数组10. js数组去重11. 找出数组最大值12. 给字符串新增方法实现功能…...

DeepSeek:开启教育测评智能化新时代

目录 一、引言二、DeepSeek 技术概述2.1 DeepSeek 的发展历程与特点2.2 工作原理与技术架构 三、测评试题智能生成3.1 生成原理与技术实现3.2 生成试题的类型与应用场景3.3 优势与面临的挑战 四、学生学习评价报告4.1 评价指标体系与数据来源4.2 DeepSeek 生成评价报告的流程与…...

【2025五一数学建模竞赛B题】 矿山数据处理问题|建模过程+完整代码论文全解全析

你是否在寻找数学建模比赛的突破点&#xff1f;数学建模进阶思路&#xff01; 作为经验丰富的美赛O奖、国赛国一的数学建模团队&#xff0c;我们将为你带来本次数学建模竞赛的全面解析。这个解决方案包不仅包括完整的代码实现&#xff0c;还有详尽的建模过程和解析&#xff0c…...

智能制造环形柔性生产线实训系统JG-RR03型模块式环形柔性自动生产线实训系统

智能制造环形柔性生产线实训系统JG-RR03型模块式环形柔性自动生产线实训系统 一、产品概述 (一)组成 柔性系统须有五个分系统构成即&#xff1a;数字化设计分系统、模拟加工制造分系统、检测装配分系统、生产物分流系统和信息管理分系统。它应包含供料检测单元&#xff0c;操作…...

1.2.2.1.4 数据安全发展技术发展历程:高级公钥加密方案——同态加密

引言 在密码学领域&#xff0c;有一种技术被图灵奖得主、著名密码学家Oded Goldreich誉为"密码学圣杯"&#xff0c;那就是全同态加密&#xff08;Fully Homomorphic Encryption&#xff09;。今天我们就来聊聊这个神秘而强大的加密方案是如何从1978年的概念提出&…...

Java大师成长计划之第18天:Java Memory Model与Volatile关键字

&#x1f4e2; 友情提示&#xff1a; 本文由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;平台gpt-4o-mini模型辅助创作完成&#xff0c;旨在提供灵感参考与技术分享&#xff0c;文中关键数据、代码与结论建议通过官方渠道验证。 在Java多线程编程中&#xff0c;线程…...

Lua再学习

因为实习的项目用到了Lua&#xff0c;所以再来深入学习一下 函数 函数的的多返回值 Lua中的函数可以实现多返回值&#xff0c;实现方法是再return后列出要返回的值的列表&#xff0c;返回值也可以通过变量接收到&#xff0c;变量不够也不会影响接收对应位置的返回值 Lua中传…...

GitLab搭建与使用(SSH和Docker)两种方式

前言 目前公共的代码仓库有很多&#xff0c;比如:git、gitee等等仓库但是我们在公司中&#xff0c;还是要搭建属于本公司自己的一个代码仓库&#xff0c;原因有如下几点 代码私密性&#xff0c;我们公司开发的代码保密性肯定一级重要&#xff0c;那么我们放到公网上&#xff0c…...

Linux数据库篇、第零章_MySQL30周年庆典活动

MySQL考试报名网站 Oracle Training and Certification | Oracle 中国 活动时间 2025年 MySQL的30周年庆典将于2025年举行。MySQL于1995年首次发布&#xff0c;因此其30周年纪念日是2025年。为了庆祝这一里程碑&#xff0c;MySQL将提供免费的课程和认证考试&#xff0c;活动…...

Windows ABBYY FineReader 16 Corporate 文档转换、PDF编辑和文档比较

作为一名合格的工人&#xff0c;日常工作肯定离不开PDF文件&#xff0c;所以今天给大家找来了一款全新的PDF处理工具&#xff0c;保证能给你带来不一样的体验。 软件介绍 这是一个全能型的PDF处理器&#xff0c;集优秀的文档转换、PDF编辑和文档比较等功能于一身&#xff0c;…...

设计模式简述(十九)桥梁模式

桥梁模式 描述基本组件使用 描述 桥梁模式是一种相对简单的模式&#xff0c;通常以组合替代继承的方式实现。 从设计原则来讲&#xff0c;可以说是单一职责的一种体现。 将原本在一个类中的功能&#xff0c;按更细的粒度拆分到不同的类中&#xff0c;然后各自独立发展。 基本…...

【每日一题 | 2025年5.5 ~ 5.11】搜索相关题

个人主页&#xff1a;Guiat 归属专栏&#xff1a;每日一题 文章目录 1. 【5.5】P3717 [AHOI2017初中组] cover2. 【5.6】P1897 电梯里的尴尬3. 【5.7】P2689 东南西北4. 【5.8】P1145 约瑟夫5. 【5.9】P1088 [NOIP 2004 普及组] 火星人6. 【5.10】P1164 小A点菜7. 【5.11】P101…...

C语言速成之08循环语句全解析:从基础用法到高效实践

C语言循环语句全解析&#xff1a;从基础用法到高效实践 大家好&#xff0c;我是Feri&#xff0c;12年开发经验的程序员。循环语句是程序实现重复逻辑的核心工具&#xff0c;掌握while、do-while、for的特性与适用场景&#xff0c;能让代码更简洁高效。本文结合实战案例&#xf…...

多模态大语言模型arxiv论文略读(六十九)

Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文标题&#xff1a;Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文作者&#xff1a;Yue Zha…...

云计算-容器云-部署CICD-jenkins连接gitlab

安装 Jenkins 将Jenkins部署到default命名空间下。要求完成离线插件的安装,设置Jenkins的登录信息和授权策略。 上传BlueOcean.tar.gz包 [root@k8s-master-node1 ~]#tar -zxvf BlueOcean.tar.gz [root@k8s-master-node1 ~]#cd BlueOcean/images/ vim /etc/docker/daemon.json…...

精讲C++四大核心特性:内联函数加速原理、auto智能推导、范围for循环与空指针进阶

前引&#xff1a;在C语言长达三十余年的演进历程中&#xff0c;每一次标准更新都在试图平衡性能与抽象、控制与安全之间的微妙关系。从C11引入的"现代C"范式开始&#xff0c;开发者得以在保留底层控制能力的同时&#xff0c;借助语言特性大幅提升代码的可维护性与安全…...

【HarmonyOS 5】鸿蒙中常见的标题栏布局方案

【HarmonyOS 5】鸿蒙中常见的标题栏布局方案 一、问题背景&#xff1a; 鸿蒙中常见的标题栏&#xff1a;矩形区域&#xff0c;左边是返回按钮&#xff0c;右边是问号帮助按钮&#xff0c;中间是标题文字。 那有几种布局方式&#xff0c;分别怎么布局呢&#xff1f;常见的思维…...

Docker 部署 - Crawl4AI 文档 (v0.5.x)

Docker 部署 - Crawl4AI 文档 (v0.5.x) 快速入门 &#x1f680; 拉取并运行基础版本&#xff1a; # 不带安全性的基本运行 docker pull unclecode/crawl4ai:basic docker run -p 11235:11235 unclecode/crawl4ai:basic# 带有 API 安全性启用的运行 docker run -p 11235:1123…...

QuecPython+Aws:快速连接亚马逊 IoT 平台

提供一个可接入亚马逊 Iot 平台的客户端&#xff0c;用于管理亚马逊 MQTT 连接和影子设备。 初始化客户端 Aws class Aws(client_id,server,port,keep_alive,ssl,ssl_params)参数&#xff1a; client_id (str) - 客户端唯一标识。server (str) - 亚马逊 Iot 平台服务器地址…...

内存安全暗战:从 CVE-2025-21298 看 C 语言防御体系的范式革命

引言 2025 年 3 月&#xff0c;当某工业控制软件因 CVE-2025-21298 漏洞遭攻击&#xff0c;导致欧洲某能源枢纽的电力调度系统瘫痪 37 分钟时&#xff0c;全球网络安全社区再次被拉回 C 语言内存安全的核心战场。根据 CISA 年度报告&#xff0c;68% 的高危漏洞源于 C/C 代码&a…...

SpringCloud Gateway知识点整理和全局过滤器实现

predicate(断言)&#xff1a; 判断uri是否符合规则 • 最常用的的就是PathPredicate&#xff0c;以下列子就是只有url中有user前缀的才能被gateway识别&#xff0c;否则它不会进行路由转发 routes:- id: ***# uri: lb://starry-sky-upmsuri: http://localhost:9003/predicate…...

全球实物文件粉碎服务市场洞察:合规驱动下的安全经济与绿色转型

一、引言&#xff1a;从纸质堆叠到数据安全的“最后一公里” 在数字化转型浪潮中&#xff0c;全球企业每年仍产生超过1.2万亿页纸质文件&#xff0c;其中包含大量机密数据、客户隐私及商业敏感信息。据QYResearch预测&#xff0c;2031年全球实物文件粉碎服务市场规模将达290.4…...

冒泡排序的原理

冒泡排序是一种简单的排序算法&#xff0c;它通过重复地遍历待排序的列表&#xff0c;比较相邻的元素并交换它们的位置来实现排序。具体原理如下&#xff1a; 冒泡排序的基本思想 冒泡排序的核心思想是通过相邻元素的比较和交换&#xff0c;将较大的元素逐步“冒泡”到列表的…...

Day22 Kaggle泰坦尼克号训练实战

​ 作业 自行学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 kaggle泰坦里克号人员生还预测 一、流程 思路概述 数据加载 &#xff1a;读取泰坦尼克号的训练集和测试集。数据预处理 &#xff1a;处理缺失值、对分类变量进行编码、…...

深入浅出之STL源码分析7_模版实例化与全特化

1.引言 显示实例话和全特化的区别&#xff0c;之前我们在讨论类模版的时候&#xff0c;讨论过&#xff0c;他俩不是同一个概念&#xff0c;类模版中你如果全特化了&#xff0c;还是需要实例化才能生成代码&#xff0c;但是对于函数模版&#xff0c;这个是不同的&#xff0c;函…...

CAPL -实现SPRMIB功能验证

系列文章目录 抑制肯定响应消息指示位&#xff08;SPRMIB&#xff09; 二十一、CANdelaStudio深入-SPRMIB的配置 文章目录 系列文章目录一、SPRMIB是什么&#xff1f;二、SetSuppressResp(long flag)三、GetSuppressResp 一、SPRMIB是什么&#xff1f; 正响应&#xff1a;表示…...

2025 Mac常用软件安装配置

1、homebrew 2、jdk 1、使用brew安装jdk&#xff1a; brew install adoptopenjdk/openjdk/adoptopenjdk8 jdk默认安装位置在 /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home 目录。 2、配置环境变量&#xff1a; vim ~/.zshrc# Jdk export JAVA_HOM…...

容器技术 20 年:颠覆、重构与重塑软件世界的力量

目录 容器技术发展史 虚拟化技术向容器技术转变 Docker的横空出世 容器编排技术与Kubernetes 微服务的出现与Istio 工业标准的容器运行时 容器技术与 DevOps 的深度融合​ 无服务架构推波助澜 展望未来发展方向 从 20 世纪硬件虚拟化的笨重&#xff0c;到操作系统虚拟…...