Java——类和对象

在Java中,类与对象是面向对象编程(OOP)的核心概念。那面向对象又是什么呢。

一、面向对象和面向过程

1、面向对象

面向对象(Object-oriented)是一种程序设计的方法和编程范式,它以对象作为程序的基本单位,通过封装、继承和多态等概念来组织和实现程序逻辑。面向对象的编程思想强调将问题分解为对象的集合,每个对象具有自己的状态(属性)和行为(方法),并通过相互之间的消息传递来实现协作和交互。

面向对象的三大基本特征:

封装(Encapsulation)

封装是将数据(属性)和行为(方法)封装在对象内部,隐藏对象的实现细节,只暴露必要的接口,实现数据的保护和模块化。

继承(Inheritance)

继承是面向对象编程的一种机制,通过继承,一个类(子类)可以继承另一个类(父类)的属性和方法,促进代码重用和扩展。

多态(Polymorphism)

多态允许同一个接口有多个实现,通过动态绑定在运行时决定具体调用哪种实现,增强代码的灵活性和可扩展性。

2、面向过程

面向过程编程(Procedural Programming)是一种以过程为中心的编程方式,将程序视为一系列的步骤或过程的集合。它关注如何完成任务,通过编写一系列的函数来实现功能,函数接受输入,执行一系列操作,并返回输出。面向过程编程强调算法和步骤的顺序,逐步解决问题。

  • 过程中心:程序由过程(函数)组成,按照执行顺序依次调用。
  • 模块化:通过函数将代码分解为模块,但函数之间可能存在紧密耦合。

3、示例

我们可以用一个例子更加生动的介绍一下这两者的区别:

面向对象

例如我们使用豆浆机打豆浆,如果在免面向对象的情况下,豆浆机、水、大豆和豆浆都是对象:

class Soy {//...
}class Water {//...
}class Soymilk {//...
}class SoymilkMaker {//...public static void addWater() {//...}public static void addSoy() {//...}public static Soymilk makeSoymilk() {//...}
}

在这个面向对象的例子中,SoymilkMaker 类封装了加水、加大豆和制作豆浆的操作。我们通过创建 SoymilkMaker 对象并调用它的方法来实现整个过程。数据(watersoy)和行为(addWateraddSoy 方法)都被封装在对象内部。

面向过程

在面向过程编程中,我们将任务分解为不同的函数,每个函数执行特定的操作。

void AddWater(Water) {//...
}void AddSoy(Soy) {//...
}Soymilk MakeSoymilk(Water, Soy) {AddWater();AddSoy();//...
}

每一个函数都有自己的任务。在这个面向过程的例子中,我们通过一系列函数调用来完成制作豆浆的过程。这些函数分别处理加水、加大豆和制作豆浆的任务。

二、类的定义和实例化

1、类和对象的关系

1)类(Class)

类可以看作是对象的模板或蓝图。它定义了对象的属性(数据)和行为(方法)。类本身是抽象的,不占用内存。

2)对象(Object)

对象是类的一个具体实例。每个对象都有独立的属性和方法。当一个类被实例化时,会在内存中创建一个对象,这个对象包含了类中定义的所有属性和方法。当对象被创建时,系统会在内存中为其分配空间来存储属性值。不同对象的属性存储在不同的位置,不会互相干扰。

3)之间的关系

类就是一种数据类型,它只能说是一种模版,例如 int 和 double 等类型。而对象是类的实例,就像是使用类这个数据类型创建了一个变量,就像 int a; 这里的 a 就像一个实例一样,它在内存中是有被分配空间的。

4)图解

2、类的定义

类的声明使用class关键字,后跟类名,通常遵循大驼峰命名法(即每个单词的首字母大写)。类名紧跟着一对花括号,花括号内包含类的成员(属性和方法)。

// 类的定义模板
访问修饰符 class 类名 {// 成员变量(属性)访问修饰符 数据类型 变量名;// 构造方法,构造方法不需要返回类型访问修饰符 类名(参数列表) {// 构造方法的实现}// 成员方法访问修饰符 返回类型 方法名(参数列表) {// 方法的实现}
}

例如:

class Person {//人的属性private String name;//名字private int age;//年龄//构造方法public Person(String name,int age) {this.name = name;this.age = age;}//公共方法显示信息public void printInfo() {System.out.println("name:" + this.name + "age:" + this.age);}// 公有的 getter 方法public String getName() {return name;}public int getAge() {return age;}//...
}

3、类的实例化

1)使用 new 关键字创建实例

当我们有了一个类,我们可以将这个类实例化,也就是通过这个类创建一个对象(实例)。

下面是最常见的实例化方式,使用 new 关键字来调用类的构造方法创建一个类的实例。

public class Test {public static void main(String[] args) {Person person1 = new Person("张三",18);Person person2 = new Person("李四",19);System.out.println("person1 " + person1.getName() + " " +  person1.getAge());System.out.println("person2 " + person2.getName() + " " +  person2.getAge());}
}class Person {//人的属性private String name;//名字private int age;//年龄//构造方法public Person(String name,int age) {this.name = name;this.age = age;}//公共方法显示信息public void printInfo() {System.out.println("name:" + this.name + "age:" + this.age);}// 公有的 getter 方法public String getName() {return name;}public int getAge() {return age;}//...
}

类可以定义多个构造方法,通过传入不同的参数来实例化对象。也就是构造方法重载

// 定义一个类
class Person {private String name;private int age;// 无参构造方法public Person() {this.name = "Unknown";this.age = 0;}// 参数为String和int的构造方法public Person(String name, int age) {this.name = name;this.age = age;}public void displayInfo() {System.out.println("Name: " + name + ", Age: " + age);}
}public class Main {public static void main(String[] args) {// 使用 new 关键字使用无参构造方法实例化类Person person1 = new Person();person1.displayInfo();// 使用 new 关键字使用参数为String和int的构造方法实例化类Person person2 = new Person("张三", 18);person2.displayInfo();}
}

还可以使用工厂方法模式。工厂方法模式是通过定义一个工厂类来封装对象的实例化过程。

// 定义一个类
class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public void displayInfo() {System.out.println("Name: " + name + ", Age: " + age);}
}// 定义一个工厂类
class PersonFactory {public static Person createPerson(String name, int age) {return new Person(name, age);}
}public class Main {public static void main(String[] args) {// 使用工厂方法实例化类Person person = PersonFactory.createPerson("李四", 19);person.displayInfo();}
}

2)使用反射机制

反射机制允许在运行时动态地获取类的信息,并实例化类。

public class Main {public static void main(String[] args) {try {// 使用反射机制实例化类Class<?> cls = Class.forName("Person");Person person = (Person) cls.getDeclaredConstructor().newInstance();person.displayInfo();} catch (Exception e) {e.printStackTrace();}}
}

3)单例模式

单例模式确保一个类只有一个实例,并提供全局访问点。

// 定义一个类
class Singleton {private static Singleton instance = null;private Singleton() {// 私有构造方法,防止外部实例化}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}public void displayInfo() {System.out.println("This is a singleton instance.");}
}public class Main {public static void main(String[] args) {// 使用单例模式实例化类Singleton singleton = Singleton.getInstance();singleton.displayInfo();}
}

以上几种实例化类的方法各有其使用场景:

  1. 使用关键字 new:最常见、最直接的实例化方式。
  2. 使用构造方法重载:允许灵活地通过不同参数创建实例。
  3. 使用反射机制:用于需要动态加载和实例化类的场景,如插件框架。
  4. 使用工厂方法模式:封装实例化过程,符合面向对象设计原则。
  5. 使用单例模式:保证类的唯一实例,适用于需要全局唯一对象的场景。

三、对象在内存中的存储

1、对象在内存中存储情况

下面我们对对象创建后再内存中的情况进行分析。

这里用以下对象实例举例:

Fish goldenFish = new Fish("goldenFish",0.25);class Fish {public String breed;public double weight;public Fish(String breed,int weight) {this.breed = breed;this.weight = weight;}public void swim() {//...}
}

这里提前介绍一下字符串常量池。在Java中,字符串的内存管理有一些特别之处。具体来说,字符串字面量(如“goldenFish”) 通常会存储在字符串常量池(String Constant Pool)中,但这会根据具体的代码实现和运行时条件有所不同。

字符串常量池是为了提高性能和减少内存消耗而设计的。它是方法区的一部分,用于存储在编译时确定的字符串常量和运行时创建的字符串常量。

当我们在代码中使用字符串字面量时,Java编译器会自动将这些字面量放入字符串常量池。例如:

String str1 = "张三";
String str2 = "张三";

在这种情况下,str1str2 都将引用同一个字符串常量池中的 "张三" 对象,因此 str1 == str2 将返回 true。因为 String 也是类,所以 str1 和 str2 都是对象引用变量,所以其中存储的都是引用,这里的字符串常量 "张三" 会被放入字符串常量池,然后 str1 和 str2 中存储的都是这一个字符串常量池中的 "张三" 的引用。所以它们中存储的引用是相等的。

字符串对象可以通过两种方式创建:

  1. 使用字符串字面量

    当使用字符串字面量(例如 String str = "张三";)时,字符串会被放入字符串常量池。如果常量池中已经存在相同内容的字符串,则直接返回该字符串的引用。然后 str 中存储的就是字符串常量池中的 "张三" 的引用。

  2. 使用 new 关键字

    当使用 new 关键字创建字符串对象时(例如 String str = new String("张三");),即使字符串常量池中已经存在相同内容的字符串,依然会在堆中创建一个新的字符串对象。

//str1 引用的是字符串常量池中的 "张三"
String str1 = "张三";
//str2 引用的是堆中的字符串对象 "张三"
String str2 = new String("张三");

因此这里的 str1 == str2 将返回 false。因为它们存储的引用是不同的。

如果我们使用一个常量字符串 "张三" 用来初始化一个 String 类型的对象,那么编译器会首先检查字符串 "张三" 是否在字符串常量池中。如果存在,则直接使用该引用;否则,将其添加到常量池中,然后再使用其引用。

在介绍了这个知识点后,我们可以接着分析我们上面的代码。

Fish goldenFish = new Fish("goldenFish",0.25);

显然我们这里使用的是常量字符串作为参数传入构造函数的,所以这里的字符串就应当在字符串常量池。

然后对于 goldenFish 这个对象引用变量,它存储的就是 goldenFish 这个对象的引用, goldenFish 这个对象的一些属性就存储在堆区。但是对于 goldenFish 的 breed 属性,是一个字符串类型,它也是一个对象,又比较特殊,这里使用的是常量字符串,所以这里的 breed 作为 String 类型对象的引用变量,存储的引用是字符串常量池中的常量字符串的引用。

对于 goldenFish 这个对象的其他属性 weight 就是直接存储在堆区的,因为它是基础类型之一的 double。

对于 goldenFish 的一些构造方法普通方法的字节码均存储在方法区中。当类被加载时,它们会被解析并存储在方法区。方法的实际执行代码在方法区中,而方法内的局部变量和方法参数在被调用时存储在栈中(与 C 语言中的函数栈帧开辟与销毁类似)。

2、对象存储图解

3、具体步骤与内存分配

类加载

  • JVM检查Fish类是否已经加载。如果没有加载,会加载Fish类,并在方法区中存储类信息,包括类的构造方法和其他方法的字节码。

对象创建

  • JVM在堆中为新的Fish对象分配内存。

成员变量初始化

  • Fish对象的成员变量进行初始化。
  • breed引用字符串常量池中的字符串"goldenFish"
  • weight直接存储在对象的内存中,因为它是基本类型double

构造方法调用

  • JVM调用Fish类的构造方法,并将参数"goldenFish"0.25传递给构造方法。
  • 构造方法对对象进行初始化,将参数值赋给对象的成员变量。

4、类和对象在内存中的分配机制

在我们创建一个对象时,就像下面这样:

Fish fish = new Fish();class Fish {public String breed;public double weight;public void swim() {//...}
}

这里的 fish 这个变量实际上是一个对象引用变量,其中存储的是真实的在堆区的对象的引用。我们上面就已经提到了。

如果我们将这个对象引用变量的值赋值个另一个对象引用变量的话,就可以通过另一个对象引用变量访问这个对象了。就像下面:

Fish fish = new Fish();
//声明一个新的对象引用变量
Fish fish2;
//将之前的对象引用变量的值赋值给新的对象引用变量
fish2 = fish;

然后 fish2 和 fish 都指向同一个对象了。

四、类的属性(成员变量 / 字段)

属性是类的一个组成部分,属性可以是任意数据类型,可以是基础数据类型也可以是引用数据类型。

1、属性的定义

属性的定义与变量的定义相似,但是属性的定义最前面会多一个访问修饰符。

变量定义:

int num;

属性定义:

访问修饰符 int num;

访问修饰符:

在Java中,访问修饰符(Access Modifiers)用于控制类、方法和属性(字段)的可见性。它们决定了其他类是否能够访问特定的类成员(属性或方法)。Java中有四种主要的访问修饰符:

  1. public
  2. protected
  3. (什么都不写时的访问级别为默认)
  4. private
修饰符当前类同一个包子类(不同包)其他包
public
protected×
默认××
private×××

2、属性的默认值

属性定义后不初始化,会有默认初始值,与数组元素的默认初始值同样。

intshortbytelongfloatdoublecharbooleanString
0000L0.0f0.0\u0000falsenull

我们可以使用代码验证:

public class Test {public static void main(String[] args) {Fish fish = new Fish();System.out.println("breed " + fish.breed);System.out.println("age " + fish.age);System.out.println("weight " + fish.weight);}
}class Fish {String breed;int age;float weight;//...
}

运行结果:

3、对象访问其属性

在Java中,对象通过点(.)操作符来访问其属性和方法。我们上面已经给出了很多例子了。

五、类的成员方法

类的成员方法简称方法。在Java中,类的成员方法(也称为实例方法或成员函数)是定义在类内部的函数,用于实现类的对象的行为。成员方法可以访问和修改类的属性,并可以与其他方法进行交互。

1、方法的定义

成员方法可以包含以下几部分:

  1. 访问修饰符:控制方法的可见性(如publicprivateprotected、默认)。
  2. 返回类型:定义方法返回的值类型,如果不返回任何值,使用void。对于构造方法比较特殊,构造方法不用写返回类型。
  3. 方法名:标识方法的名称。
  4. 参数列表:方法可以接受的输入参数,包含参数的类型和名称。
  5. 方法体:方法的具体实现代码。
访问修饰符 返回类型 方法名(参数列表) {//方法体
}

例如:

class Person {String name;int age;//说话方法public void speak(String sentences) {System.out.println(sentences);}//介绍方法public void introduce() {System.out.println("你好,我是" + this.name);}
}

这里的说话方法和介绍方法就是这个类的方法。

2、方法的种类

1)构造方法(构造器)

构造方法(Constructor)是用于创建和初始化类对象的一种特殊方法。在Java中,构造方法的名称必须与类名相同并且没有返回类型(即使是void也不能写)。构造方法在创建对象时自动调用,它可以用于初始化对象的属性或执行任何需要在对象创建时完成的操作。一个类可以有多个构造方法,只要它们的参数列表不同。

构造方法在创建对象时被自动调用。使用new关键字创建对象时,系统会根据传递的参数选择合适的构造方法来调用。

public class Test {public static void main(String[] args) {Person person = new Person("张三",19);}
}class Person {String name;int age;public Person(String name,int age) {this.name = name;this.age = age;}//...
}

这里的语句:

Person person = new Person("张三",19);

就调用了构造方法,我们传入了两个参数,刚好有一个两个参数的构造方法,调用的刚好就是那一个。

如果一个类没有显式地定义任何构造方法,Java编译器会自动为该类生成一个默认的无参构造方法。这个默认的构造方法是public的,且方法体为空。例如,对于一个类Person,如果没有定义任何构造方法,编译器会自动生成如下构造方法:

public class Person {// 编译器自动生成的无参构造方法public Person() {}
}

如果你定义了一个构造方法,那么编译器不会再自动生成无参构造方法。

2)一般自定义方法

一般自定义方法,也被称为实例方法,是属于类的实例的,也就是属于对象的。它们定义在类内部,可以访问实例变量和其他实例方法。

class Person {String name;int age;//说话方法public void speak(String sentences) {System.out.println(sentences);}//介绍方法public void introduce() {System.out.println("你好,我是" + this.name);}
}

3)静态方法

静态方法属于类,而不是类的实例。静态方法使用static关键字定义,可以直接通过类名调用,而不需要创建对象。

public class MathUtils {// 静态方法public static int square(int x) {return x * x;}
}

3、方法的调用

1)构造方法调用

构造方法在创建对象时自动调用。构造方法在创建对象时被自动调用。使用new关键字创建对象时,系统会根据传递的参数选择合适的构造方法来调用。

public class Test {public static void main(String[] args) {Person person = new Person("张三",19);}
}class Person {String name;int age;public Person(String name,int age) {this.name = name;this.age = age;}//...
}

这里的语句:

Person person = new Person("张三",19);

就调用了构造方法,我们传入了两个参数,刚好有一个两个参数的构造方法,调用的刚好就是那一个。

我们这里只有一个两个参数构造方法,如果我们在创建对象时不传入参数,或者传入其他数量的参数,就会因为找不到适当的构造方法而报错:

构造方法的重载:

类可以有多个构造方法,称为构造方法的重载(Overloading)。这些构造方法具有相同的名称(即类名),但参数列表不同。

public class Test {public static void main(String[] args) {Person person1 = new Person("张三",19);//调用两个参数的构造方法Person person2 = new Person();//调用无参数的构造方法}
}class Person {String name;int age;//无参数的构造方法public Person() {this.name = "未知";this.age = 0;}//两个参数的构造方法public Person(String name,int age) {this.name = name;this.age = age;}//...
}

2)一般自定义方法调用

一般自定义方法要创建对象,然后通过对象调用相应的方法。

public class Test {public static void main(String[] args) {Person person = new Person();person.name = "张三";person.age = 19;person.introduce();//调用一般自定义方法}
}class Person {String name;int age;//说话方法public void speak(String sentences) {System.out.println(sentences);}//介绍方法public void introduce() {System.out.println("你好,我是" + this.name);}
}

运行结果:

3)静态方法调用

静态方法可以通过类名调用。

public class MathUtils {// 静态方法public static int square(int x) {return x * x;}public static void main(String[] args) {// 调用静态方法System.out.println(MathUtils.square(5));  // 输出:25}
}

对于 square 就是一个静态方法,它可以直接通过类名进行调用。

4)直接调用

在同一个类中,可以直接通过方法名进行调用。

public class Example {public static void main(String[] args) {sayHello();}public static void sayHello() {System.out.println("Hello, World!");}
}

5)方法的重载(Overloading)

在同一个类中,可以定义多个方法(包括构造方法,构造方法也可以重载),它们具有相同的名称但参数列表不同,这称为方法重载。对于这种情况调用时传入不同的参数,使用的方法是不同的。

public class Calculator {// 方法重载:同名方法,参数不同public int add(int a, int b) {return a + b;}public double add(double a, double b) {return a + b;}public int add(int a, int b, int c) {return a + b + c;}public static void main(String[] args) {Calculator calc = new Calculator();System.out.println(calc.add(1, 2));         // 调用第一个add方法System.out.println(calc.add(1.5, 2.5));     // 调用第二个add方法System.out.println(calc.add(1, 2, 3));      // 调用第三个add方法}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/346616.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 异常值检测与处理——Z-score法

目录 一、算法原理1、算法概述2、主要函数3、参考文献二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、算法概述 使用Z分数法,可以找出距离平均值有多少个标准差值…

品牌渠道健康发展的关键与方法

一个品牌的渠道健康与否对其长期发展至关重要。品牌虽多&#xff0c;但并非所有产品都能成为品牌&#xff0c;创建品牌需大量精力&#xff0c;而让品牌长久健康发展则需多方面努力。 力维网络服务众多知名品牌&#xff0c;总结出一些渠道治理方法供品牌参考。首先&#xff0c;管…

前端JS必用工具【js-tool-big-box】学习,获取当前浏览器向上滚动还是向下滚动,获取当前距离顶部和底部的距离

这一小节&#xff0c;我们说一下 js-tool-big-box 添加的最新工具方法&#xff0c;在日常前端开发工作中&#xff0c;如果网页很长&#xff0c;我们就需要获取当前浏览器是在向上滚动&#xff0c;还是向下滚动。如果向上滚动&#xff0c;滚动到0的时候呢&#xff0c;需要做一些…

【Mongodb】Mongodb亿级数据性能测试和压测

一&#xff0c;mongodb数据性能测试 如需转载&#xff0c;请标明出处&#xff1a;https://zhenghuisheng.blog.csdn.net/article/details/139505973 mongodb数据性能测试 一&#xff0c;mongodb数据性能测试1&#xff0c;mongodb数据库创建和索引设置2&#xff0c;线程池批量…

React+TS前台项目实战(六)-- 全局常用组件Button封装

文章目录 前言Button组件1. 功能分析2. 代码注释说明3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局按钮组件封装&#xff0c;可根据UI设计师要求自定义修改。 Button组件 1. 功能分析 &#xff08;1&#xff09;可以通过className属性自定义按钮样式&#xff0c;传递…

【计算机网络基础】OSI七层网络模型 TCPIP四层网络模型

文章目录 ISO介绍网络模型介绍OSI七层模型OSI七层模型介绍OSI七层特点一、TCP/IP四层模型介绍二、TCP/IP四层模型TCP/IP协议簇一次C/S通信 &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f388;欢迎踏入我的博客世界&#xff0c;能与您在此邂逅&#xff0c;真是缘分…

校验参数个数工具类

项目中有个需求&#xff1a;前后端参数一致性校验&#xff0c;在某业务场景下后端代码需要校验参数个数&#xff0c;因此设计了1个工具类方便大伙使用&#xff0c;特此简单记录下。 校验参数个数工具类 一、校验工具类CheckNumInsideParamters二、单元测试ParameterSizeTest三…

从零手写实现 nginx-17-nginx.conf 全局的默认配置

前言 大家好&#xff0c;我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的&#xff0c;可以参考我的另一个项目&#xff1a; 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …

哪里有宣传海报制作模板?盘点可以套用的海报软件

不论是精心筹备的盛会、充满爱意的婚礼仪式&#xff0c;还是家庭聚会的温馨时光&#xff0c;一份设计精巧的邀请函都是主人诚挚邀请的最好证明。它不仅传递着邀请&#xff0c;更承载着对宾客的尊重与期待。但你知道在哪里可以找到那些让人眼前一亮的邀请函海报制作模板吗&#…

Simscape Multibody与RigidBodyTree:机器人建模

RigidBodyTree&#xff1a;主要用于表示机器人刚体结构的动力学模型&#xff0c;重点关注机器人的几何结构、质量和力矩&#xff0c;以及它们如何随时间变化。它通常用于计算机器人的运动和受力情况。Simscape Multibody&#xff1a;作为Simscape的一个子模块&#xff0c;专门用…

ICRA 2024:北京工业大学马楠教授联合中科原动力公司推出番茄采摘自主机器人AHPPEBot,实现32.46秒快速准确采摘

当前&#xff0c;农业生产正深受劳动力短缺困扰&#xff0c;这一现状对生产规模的进一步拓展构成了严重制约。为了突破这一瓶颈&#xff0c;实施自动化已成为提升农业生产力的关键途径&#xff0c;这也使得机器人采收技术备受关注。 现今的机器人采收系统普遍采用先进感知方法&…

Android面试题之说说系统的启动流程(总结)

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 启动流程 Boot Rom -> Boot Loader -> Kernel -> 启动Init进程 -> Zygote进程 -> system_server进程 -> 启动AMS、WMS、PMS…

linux 服务器上离线安装 node nvm

因为是离线环境 如果你是可以访问外网的 下面内容仅供参考 也可以继续按步骤来 node 安装路径 Node.js — Download Node.js nvm 安装路径 Tags nvm-sh/nvm GitHub 后来发现 nvm安装后 nvm use 版本号 报错 让我去nvm install 版本 我是内网环境 install不了 下面 你要 把安…

Nginx 配置防护 缓慢的 HTTP拒绝服务攻击+点击劫持:X-Frame-Options未配置

一 安全团队检测网站 1 检测到目标主机可能存在缓慢的HTTP拒绝服务攻击 缓慢的HTTP拒绝服务攻击是一种专门针对于Web的应用层拒绝服务攻击&#xff0c;攻击者操纵网络,对目标Web服务器进行海量HTTP请求攻击&#xff0c;直到服务器带宽被打满&#xff0c;造成了拒绝服务。 慢…

Macbook M芯片Homebrew与git的安装与配置

Macbook M芯片Homebrew与git的安装与配置 Homebrew的安装与配置 搜索Homebrew; 找到如下网址https://brew.sh/ 把以上命令复制到终端 执行后&#xff0c;发现并不能下载&#xff1b; 如果你像我一样也是不通的&#xff0c;可以使用国内源,将如下命令复制到终端&#xff1a;…

选课清单--数据结构课程设计(十字链表+哈希表实现)

题目如上(九院版&#xff0c;被老师要求选这个题目做&#xff0c;不知道还有没有别的学校是这种题目&#xff0c;都可以相互借鉴hh) 代码写的有冗余&#xff0c;结构体应该有三个&#xff0c;一个学生&#xff0c;一个课程&#xff0c;一个十字链表的结构体&#xff0c;如果公…

数据结构初阶 · 链式二叉树的部分问题

目录 前言&#xff1a; 1 链式二叉树的创建 2 前序 中序 后序遍历 3 树的节点个数 4 树的高度 5 树的叶子节点个数 6 树的第K层节点个数 前言&#xff1a; 链式二叉树我们在C语言阶段已经实现了&#xff0c;这里介绍的是涉及到的部分问题&#xff0c;比如求树的高度&am…

2024年6月8日,骑行杨柳冲峡谷:一场心灵与自然的交响曲

引言&#xff1a;寻找生活的节奏在这个快节奏的时代&#xff0c;我们常常迷失在都市的喧嚣中&#xff0c;忘记了如何聆听内心的声音。2024年6月8日&#xff0c;我与一群志同道合的校卡骑行群骑友&#xff0c;踏上了前往杨柳冲峡谷的旅程&#xff0c;这不仅仅是一次简单的户外活…

远程咨询的好处都有哪些呢?

随着科技的飞速发展&#xff0c;远程咨询正逐渐成为人们获取医疗服务的一种新方式。那么什么是远程咨询呢&#xff1f;其又有哪些好处呢&#xff1f;下面就给大家详细地说说。 远程咨询的概念 远程咨询&#xff0c;顾名思义&#xff0c;是指通过互联网技术&#xff0c;实现患…

nlp学习笔记

目录 很多入门例子 bert chinese 很多入门例子 https://github.com/lansinuote/Huggingface_Toturials bert chinese import torch import torch.nn as nn from transformers import AutoTokenizer, AutoModel, BertModel, TFBertModel, BertTokenizer# youpath = D:/bert-…