Java面向对象(详细解释)
第一章 Static关键字
1.static的介绍以及基本使用
1.概述:static是一个静态关键字
2.使用:
a.修饰一个成员变量:
static 数据类型 变量名
b.修饰一个方法:
修饰符 static 返回值类型 方法名(形参){
方法体
return 结果
}
3.调用静态成员:
类名直接调用(不用new对象)
4.静态成员特点:
静态成员属于类成员,不属于对象成员(非静态成员属于对象成员)
静态成员会随着类的加载而加载
静态成员优先于非静态成员存在在内存中
凡是根据静态成员所在的类创建出来的对象都可以共享这个静态成员
public class Student {String name;int age;static String ClassRoom;}
public class Test01 {public static void main(String[] args) {//先给静态成员赋个值Student.ClassRoom = "后陡门58号";Student s1 = new Student();s1.name = "张钥沅";s1.age = 26;
// s1.ClassRoom = "后陡门58号";System.out.println(s1.name+","+s1.age+","+Student.ClassRoom);System.out.println("========================");Student s2 =new Student();s2.name = "路卓豪";s2.age = 29;
// s2.ClassRoom = "后陡门58号";System.out.println(s2.name+","+s2.age+","+Student.ClassRoom);}
}
2.static修饰成员的访问特点
1.在静态方法中能直接访问非静态成员吗?不能
想要调用的话需要先new对象调用
2.在非静态方法中能直接访问静态成员吗?能
同类中可以直接调用,也可以类名调用
不同类中类名调用
3.在静态方法中能直接访问静态成员吗?能
同类中可以直接调用,也可以类名调用
不同类中类名调用
4.在非静态方法中能直接访问非静态成员吗?能
同类直接调用,也可以new对象调用
不同类new对象调用
总结:
1.不管在不在同一个类中,非静态成员都可以new对象调用
2.不管在不在同一个类中,静态成员都可以类名调用
问题1:既然static成员那么好使(类名直接调用),那么我们在实际开发中,能不能将所有的成员都定义成静态的?不能
由于静态成员会随着类的加载而加载,如果将所有的成员都定义成静态的,那么类一加载静态成员都会进内存,会大量占用内存空间,所以说不能把所有的成员定义成静态成员
问题2:静态成员都啥时候定义?
一般情况下,我们在抽取工具类的时候,可以将工具类中所有的成员都定义成静态的
问题3:啥时候定义工具类?
我们在写代码的时候发现有的功能在反复实现,代码一样功能一样,此时就可以抽取出来,形成工具类
public class ArraysUtils {/*构造方法用private修饰工具类中的成员都是静态的,静态成员都是类名调用,不需要new对象所以工具类中的构造方法都是private修饰如果构造方法被private修饰,那么在别的类中就不能利用构造方法new对象* */private ArraysUtils(){}//定义一个方法,实现获取int数组最大值public static int getMax(int[] arr){int max =arr[0];for (int i=1;i<arr.length;i++){if (max<arr[i]){max = arr[i];}}return max;}
}
public class Test01 {public static void main(String[] args) {int[] arr = {5,34,7,3,45,12};
// int max = arr[0];
// for (int i=1;i<arr.length;i++){
// if (max<arr[i]){
// max = arr[i];
// }
// }
// System.out.println("max = " + max);int max = ArraysUtils.getMax(arr);System.out.println("max = " + max);}
}
public class Test02 {public static void main(String[] args) {int[] arr = {2,354,56,78,54,3,65,6};
// int max =arr[0];
// for (int i=1;i<arr.length;i++){
// if (max<arr[i]){
// max = arr[i];
// }
// }
// System.out.println("max = " + max);int max = ArraysUtils.getMax(arr);System.out.println(max);}
}
第二章 可变参数
需求:定义一个方法,实现n个整数相加
分析:
方法参数位置,只明确参数类型,但是不明确参数个数,此时就可以定义成可变参数
1.可变参数的使用和注意事项
1.定义格式:
数据类型...变量名
2.注意:
可变参数的本质是一个数组
参数位置不能连续写多个可变参数,而且当可变参数和其他普通参数一起使用时,可变参数需要放到列表最后
public class Demo01Var {public static void main(String[] args) {sum(1,2,3,4,5);sum1(1,1,2,3,4,5);}public static void sum(int...arr){int sum = 0;for (int i = 0; i < arr.length; i++) {sum+=arr[i];}System.out.println(sum);}public static void sum1(int i,int...arr){}
}
2.可变参数的练习
需求1:返回n个字符串拼接结果,如果没有传入字符,那么返回经字符串“”
public class Demo02Var {public static void main(String[] args) {/*返回n个字符串拼接结果,如果没有传入字符,那么返回经字符串“”*/String str = concat("蒋敦豪","鹭卓","李耕耘","李昊","赵一博","卓沅","赵小童");System.out.println("str = " + str);}public static String concat(String...s){String str = "";for (int i= 0;i<s.length;i++){str+=s[i];}return str;}
}
需求2:n个字符串进行拼接,每一个字符串之间使用某字符进行分隔,如果没有字符串,那么返回空字符串“”
public class Demo03Var {public static void main(String[] args){/*n个字符串进行拼接,每一个字符串之间使用某字符进行分隔,如果没有字符串,那么返回空字符串“”*/String str = concat("-","蒋敦豪","鹭卓","李耕耘");System.out.println("str = " + str);}public static String concat(String s1,String...s2){String str = "";for (int i = 0; i < s2.length; i++) {if (i!=s2.length-1){
// str = str+s2[i]+s1;str+=s2[i]+s1;}else {str+=s2[i];}}return str;}
}
第三章 递归
1.概述:方法内部自己调用自己
2.分类:
a.直接递归:
public static meyhod(){
method();
}
b.间接递归:
A(){
B();
}
B(){
C();
}
C(){
A();
}
3.注意:
递归必须要有出口,否则就会出现栈内存溢出
递归即使有出口,递归次数也不要太多
public class Demo01Recursion {public static void main(String[] args) {method();}public static void method(){method();}
}
示例1:利用递归输出3到1
法1:
public class Demo02Recursion {public static void main(String[] args) {method(3);}public static void method(int i){System.out.print(i+" ");if (i-1>0){method(i-1);}}
}
法2:
public class Demo02Recursion {public static void main(String[] args) {method(3);}// public static void method(int i){
// System.out.print(i+" ");
// if (i-1>0){
// method(i-1);
// }
// }public static void method(int i){if (i==1){System.out.println(i);//结束方法return;}System.out.print(i+" ");method(i-1);}
}
示例2:求n!(n的阶乘)
需求:定义一个方法,完成3的阶乘 3*2*1
分析:假如定义一个方法,代表n的阶乘 ->method(n) n接收几,就代表几的阶乘
public class Demo03Recursion {public static void main(String[] args) {int method = method(3);System.out.println(method);}public static int method(int i){if (i==1){return 1;}return i*method(i-1);}
}
示例3:求斐波那契数列
规律:一个数等于前两个数之和,比如 1,1,2,3,5,8,13,21,34,55......
public class Demo04Recursion {public static void main(String[] args) {int result = method(12);System.out.println("result = " + result);}public static int method(int month){if(month==1||month==2){return 1;} else {return method(month-1)+method(month-2);}}
}
第四章 数组常见算法
1.数组翻转
1.概述:数组对称索引位置上的元素互换
法1:
public class Demo01Arrays {public static void main(String[] args) {int[] arr1 = {1,2,3,4,5,6,7};int[] arr2 = Reverse(arr1);for (int i=0;i<arr1.length;i++){System.out.print(arr1[i]+" ");}System.out.println();for (int i=0;i<arr2.length;i++){System.out.print(arr2[i]+" ");}}public static int[] Reverse(int[] arr){if (arr.length!=0){int[] newarr = new int[arr.length];int min = 0;int max = newarr.length-1;int mid = (min+max)/2;for (int i=0;i<=mid;i++){newarr[min] = arr[max];newarr[max] = arr[min];min++;max--;}return newarr;}else {return arr;}}
}
法2:
public class Demo02Arrays {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7};for (int min =0,max=arr.length-1; min<max ;min++,max--){int temp = arr[min];arr[min] = arr[max];arr[max] = temp;}for (int i = 0; i < arr.length; i++) {System.out.print( arr[i]+" ");}}
}
2.冒泡排序
数组的排序,是将数组中的元素按照大小进行排序,默认都是以升序形式进行排序,数组排序的方法很多,我们讲解的是数组的冒泡排序
排序,都要进行数组元素的大小比较,在进行位置的交换,冒泡排序是采用数组中相邻元素进行比较换位
法1:
public class Demo03Arrays {public static void main(String[] args) {int[] arr = {2,35,6,8,97,3,57};BobbleSort(arr);for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}}public static int[] BobbleSort(int[] arr) {for (int i=1;i<arr.length;i++){for (int max = arr.length - 1; max > 0; max--) {if (arr[max] < arr[max - 1]) {int temp = arr[max];arr[max] = arr[max - 1];arr[max - 1] = temp;}}}return arr;}
}
法2:
public class Demo04Arrays {public static void main(String[] args) {int[] arr = {2,35,6,8,97,3,57};BobbleSort(arr);for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}}public static int[] BobbleSort(int[] arr) {for (int i = 0; i < arr.length-1; i++) {for (int j = 0; j < arr.length-1-i; j++) {if (arr[j]>arr[j+1]){int temp = arr[j];arr[j] =arr[j+1];arr[j+1] = temp;}}}return arr;}
}
控制台输入一组数,进行冒泡排序,并且打印输出
import java.util.Scanner;public class Demo05Arrays {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入想要排序的数字个数:");int n = sc.nextInt();int[] arr = new int[n];System.out.println("请输入想要排序的"+n+"个数:");for (int i = 0; i < n; i++) {arr[i]=sc.nextInt();}boolean swapped = false;for (int j = 0; j < n-1; j++) {for (int i = 0; i < n-1-j; i++) {if (arr[i]>arr[i+1]){int temp = arr[i];arr[i] =arr[i+1];arr[i+1] =temp;swapped = true;}}if (!swapped){System.out.println("不需要排序");break;}}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}}
}
3.二分查找
1.前提:数组中的数据必须是有序的
2.查询思想:
a.老式查询:遍历数组,一个一个比较,查询效率慢
b.二分查找:每次找中间索引对应的元素进行比较查询(每次查询少一半数据)
法1:
import java.util.Scanner;public class Demo06Binary {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7};int min = 0;int max = arr.length-1;int mid = (min+max)/2;System.out.println("请输入想要查找的数:");Scanner sc = new Scanner(System.in);int n = sc.nextInt();while (min<=max){if (arr[mid]==n){System.out.println("查找成功!,索引是"+mid);break;} else if (arr[mid]<n) {min = mid+1;mid = (min+max)/2;}else {max = mid-1;mid = (min+max)/2;}}if (min>max){System.out.println("查找失败!");}}
}
法2:
import java.util.Scanner;public class Demo07Binary {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7};System.out.println("请输入欲查询数字:");Scanner sc = new Scanner(System.in);int n = sc.nextInt();int result = Binary(n,arr);if (result!=-1){System.out.println("查询成功!索引是"+result);}else {System.out.println("查询失败!");}}public static int Binary(int n,int[] arr){int min = 0;int max = arr.length-1;int mid = 0;while (min<=max){mid = (min+max)/2;if (arr[mid]<n){min = mid+1;} else if (arr[mid]>n) {max = mid-1;}else {return mid;}}return -1;}
}
第五章 数组操作
1.对象数组:
需求:定义一个长度为3的数组,存储3个Person对象,遍历数组,将3个Person对象中的属性值获取出来
public class Person {private String name;private int age;public Person(){}public Person(String name,int age) {this.name = name;this.age = age;}public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}
}
public class Demo01ObjectArray {/*定义一个长度为3的数组,存储3个Person对象,遍历数组,将3个Person对象中的属性值获取出来*/public static void main(String[] args) {Person[] arr = new Person[3];Person p1 = new Person("蒋敦豪",29);Person p2 = new Person("鹭卓",29);Person p3 = new Person("李耕耘",28);arr[0] = p1;arr[1] = p2;arr[2] = p3;/*遍历当i等于0时,arr[0]就是p1对象当i等于1时,arr[1]就是p2对象当i等于2时,arr[2]就是p3对象*/for (int i = 0; i < arr.length; i++) {System.out.println(arr[i].getName()+" "+arr[i].getAge());}}}
练习1:
(1)定义学生类Student
声明姓名和成绩成员变量
(2)测试类ObjectArrayTest的main中创建一个可以装3个学生对象的数组,并且按照学生成绩排序,显示学生信息
public class Student {private String name;private int score;public Student(){}public Student(String name,int score){this.name = name;this.score = score;}public void setName(String name){this.name = name;}public void setScore(int score){this.score = score;}public String getName(){return name;}public int getScore(){return score;}
}
public class ObjectArrayTest {public static void main(String[] args) {Student[] arr1 = new Student[3];arr1[0] = new Student("卓沅",100);arr1[1] = new Student("赵小童",98);arr1[2] = new Student("何浩楠",99);boolean swapped = false;for (int i = 0; i < arr1.length-1; i++) {for (int j = 0; j < arr1.length-1-i; j++) {if (arr1[j].getScore()<arr1[j+1].getScore()){Student temp = arr1[j];arr1[j] = arr1[j+1];arr1[j+1] = temp;swapped = true;}}if (!swapped){break;}}for (int i = 0; i < arr1.length; i++) {System.out.println(arr1[i].getName()+"..."+arr1[i].getScore());}}
}
第六章 方法参数
1.基本数据类型做方法参数传递
基本数据类型作为实参传递,传递的是值不是变量本身
方法运行,压栈保存
方法运行结束,弹栈 ->释放栈内存
public class Demo01Param {public static void main(String[] args) {int a = 10;int b = 20;/*基本数据类型当做实参传递传递的是值,不是变量本身*/method(a, b);System.out.println(a);//10System.out.println(b);//20}public static void method(int a ,int b){a+=10;b+=20;System.out.println(a);//20System.out.println(b);//40}
}
2.引用数据类型做方法参数传递
引用数据类型作为方法参数传递时,传递的是地址值而不是具体的数据
public class Demo02Param {public static void main(String[] args) {int[] arr = {10,20};method(arr);System.out.println(arr[0]);//20System.out.println(arr[1]);//40}public static void method(int[] arr){arr[0]+=10;arr[1]+=20;System.out.println(arr[0]);//20System.out.println(arr[1]);//40}
}
第七章 命令行参数(了解)
通过命令行给main方法的形参传递的实参称为命令行参数
第八章 其他操作
1.快速生成方法
1.初学者要求先定义在调用;不是初学者就可以先调用在定义方法
快捷键:Alt+回车
2.快速将一段代码抽取到一个方法中:
选中要抽取的方法,按 Ctrl + Alt + m
2.debug调试
1.概述:调试代码的一种手段
2.作用:能清楚的看到每个变量在代码执行过程中的变化,还可以找错
3.使用:在想要开始Debug的代码那一行最左边点击一下,出现红色小圆点(断点),右键点击Debug
相关文章:
Java面向对象(详细解释)
第一章 Static关键字 1.static的介绍以及基本使用 1.概述:static是一个静态关键字 2.使用: a.修饰一个成员变量: static 数据类型 变量名 b.修饰一个方法: 修饰符 static 返回值类型 方法名(形参){…...
qt ui相关的第三方库插件库
Qt UI相关的第三方库和插件库有很多,能帮助开发者提高开发效率,扩展UI功能,增强可用性和美观度。以下是一些常见的第三方库和插件: 1. QCustomPlot 功能:用于在Qt应用程序中创建交互式的二维绘图。特点:支…...
详解动态规划算法
动态规划 一、动态规划的核心思想二、动态规划的步骤1. 定义状态(State)2. 确定状态转移方程(State Transition Equation)3. 确定边界条件(Base Case)4. 填表(Table Filling)或递归计…...
LINUX网络基础 [五] - HTTP协议
目录 HTTP协议 预备知识 认识 URL 认识 urlencode 和 urldecode HTTP协议格式 HTTP请求协议格式 HTTP响应协议格式 HTTP的方法 HTTP的状态码 编辑HTTP常见Header HTTP实现代码 HttpServer.hpp HttpServer.cpp Socket.hpp log.hpp Makefile Web根目录 H…...
慕慕手记项目日志 项目从开发到部署多环境配置 2025-3-8
慕慕手记项目日志 项目从开发到部署多环境配置 2025-3-8 现在是已经到了课程的第十章了,开始进行配置项目环境了。现在要完成的任务是项目可以正常运行,而且可以自由切换配置,开发/测试。 下面是当前的目录结构图: 现在来解释一…...
华为配置篇-OSPF基础实验
OSPF 一、简述二、常用命令总结三、实验3.1 OSPF单区域3.2 OSPF多区域3.3 OSPF 的邻接关系和 LSA 置底 一、简述 OSPF(开放式最短路径优先协议) 基本定义 全称:Open Shortest Path First 类型:链路状态路由协议(IGP&…...
闭包:JavaScript 中的隐形大杀器
你可能已经在很多地方听说过闭包这个词,尤其是涉及到 JavaScript 的作用域和异步操作时。闭包是 JavaScript 中非常核心的概念,然而它又非常容易让开发者感到困惑。今天我们就来深入剖析闭包,帮助你真正理解它的工作原理,以及如何…...
【消息队列】数据库的数据管理
1. 数据库的选择 对于当前实现消息队列这样的一个中间件来说,具体要使用哪个数据库,是需要稍作考虑的,如果直接使用 MySQL 数据库也是能实现正常的功能,但是 MySQL 也是一个客户端服务器程序,也就意味着如果想在其他服…...
玩转ChatGPT:GPT 深入研究功能
一、写在前面 民间总结: 理科看Claude 3.7 Sonnet 文科看DeepSeek-R1 那么,ChatGPT呢? 看Deep Research(深入研究)功能。 对于科研狗来说,在这个文章爆炸的时代,如何利用AI准确、高效地收…...
Centos8部署mongodb报错记录
使用mongo ops安装mongodb6.0.4副本集报错 error while loading shared libraries: libnetsnmpmibs.so.35: cannot open shared object file: No such file or directory 解决 yum install net-snmp net-snmp-devel -y建议:初始化系统时把官网上的依赖包都装一遍 即…...
2024四川大学计算机考研复试上机真题
2024四川大学计算机考研复试上机真题 2024四川大学计算机考研复试机试真题 历年四川大学计算机考研复试机试真题 在线评测:https://app2098.acapp.acwing.com.cn/ 分数求和 题目描述 有一分数序列: 2/1 3/2 5/3 8/5 13/8 21/13… 求出这个数列的前 …...
前端面试题 口语化复述解答(从2025.3.8 开始频繁更新中)
背景 看了很多面试题及其答案。但是过于标准化,一般不能直接用于回复面试官,这里我将总结一系列面试题,用于自我复习也乐于分享给大家,欢迎大家提供建议,我必不断完善之。 Javascript ES6 1. var let const 的区别…...
更多文章请查看
更多文章知识请移步至下面链接,期待你的关注 如需查看新文章,请前往: 博主知识库https://www.yuque.com/xinzaigeek...
vulnhub靶场之【digitalworld.local系列】的vengeance靶机
前言 靶机:digitalworld.local-vengeance,IP地址为192.168.10.10 攻击:kali,IP地址为192.168.10.6 kali采用VMware虚拟机,靶机选择使用VMware打开文件,都选择桥接网络 这里官方给的有两种方式ÿ…...
MySql的安装及数据库的基本操作命令
1.MySQL的安装 1.1进入MySQL官方网站 1.2点击下载 1.3下拉选择MySQL社区版 1.4选择你需要下载的版本及其安装的系统和下载方式 直接安装以及压缩包 建议选择8.4.4LST LST表明此版本为长期支持版 新手建议选择红框勾选的安装方式 1.5 安装包下载完毕之后点击安装 2.数据库…...
中性点直接接地电网接地故障Simulink仿真
1.模型简介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2017Ra)软件。建议采用matlab2017 Ra及以上版本打开。(若需要其他版本可联系代为转换) 2.系统仿真图: 3.中性点直接接地电网接地故障基本概念(本仿…...
Linux16-数据库、HTML
数据库: 数据存储: 变量、数组、链表-------------》内存 :程序运行结束、掉电数据丢失 文件 : 外存:程序运行结束、掉电数据不丢失 数据库: …...
SpireCV荣获Gitee 最有价值开源项目称号
什么是GVP? GVP全称Gitee Valuable Project,意思为Gitee最有价值开源项目。作为GVP称号的获得者,SpireCV在开源社区中展现出了卓越的实力和影响力,为开源软件的发展和推广做出了积极的贡献。 这一荣誉不仅充分肯定了过去阿木实验…...
open-webui+deepseek api实现deepseek自由
虽然deepseek是免费的,但是官网的体验感太差。 所以才会有某种想法,想要更加舒服的使用deepseek。 1.Python虚拟环境 这个我就不多赘述,切记Python版本一定要和open-webui制定的版本一致。 2.deepseek api 去这个网站充点钱(…...
Hadoop八股
Hadoop八股 HadoopMapReduce考点MR on Yarn 分布式工作原理shuffle:MapTask 和 ReduceTask的处理流程MR中的MapTask 和 ReduceTask 的数量决定MR和Spark两者Shuffle的区别简单讲一下map- reduce 原理**MapReduce 的核心概念****MapReduce 的工作流程****MapReduce 的…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
