Java接口(interface)

接口(interface)明确了描述类被授权了哪些能力,但不会指定具体的方式。实现类(implement)一个或多个接口。–>使类完成了实现,是一种对于行为规范的准则的抽象。

个体的方法可以在子类中自写展现,当多个子类均拥有相同的需求的时候就需要凭借接口来快速的高效的完成。
接口是一种规范或契约,它只包含方法的声明,没有方法的实现。
	一个类可以实现一个或多个接口,并提供接口中定义的所有方法的具体实现。

Java接口(interface)

  • < 1 >明确接口中的三个关系
  • < 2 >接口中的成员:
    • [ 1 ] 成员变量:
    • ~~[ 2 ] 构造方法~~ --- >是不存在的
    • [ 3 ] 成员方法:
      • 【 1 】JDK7 :接口只能定义抽象方法
      • 【 2 】JDK8:接口可以有定义的方法体(默认,静态)
        • (1)允许接口定义默认方法,default修饰
          • Java类和多接口的时候,若多接口中存在重名的方法,而优先类中没有复写,用eclisp的快捷方式为什么只有靠近implement的接口中的方法+解决办法
            • 解决办法:
        • (2)允许接口中定义定义静态方法,需要用static修饰
      • 【 3 】JDK9:接口有私有方法:
        • (1)为什么showB需创建对象,而A的却不用
        • (2)普通的私有方法,给default默认方法服务(普通的私有方法,给默认方法服务的。default删去)
  • < 3 >对比代码
    • [ 1 ] 没有抽象方法的抽象实现类:
    • [ 2 ] 实现类是抽象类的类
  • < 4 >InterApply:
    • 代码举例[ 1 ]:
      • 分析代码:
      • 为什么在main方法中必须强转circle从Shape到Circle的时候setRadius才能用:
    • 代码举例[ 2 ]:
      • 分析:
  • < 5 > 适配器模式(Adapter Pattern):
    • 代码1
    • 代码2:

接口不同于类,其在Java是一种抽象类型的体现,将抽象的方法集中到一起。以关键字interface来声明,一个类通过继承接口的方式+关键字implement来实现我们所需的方法。

实现接口的类是抽象类,否则该类要定义接口中的所有方法。

< 1 >明确接口中的三个关系

1.> 类和类之间的继承关系:

继承可单不可多,但可多层。
	让子类继承父类的属性和方法

继承是面向对象编程中一种重要的关系,它允许一个类(子类/派生类)继承另一个类(父类/基类)的属性(数据成员)和方法(函数成员)。子类可以获得父类的属性和方法,并且可以在此基础上添加新的属性和方法,或者重写父类的方法。继承可以是单继承(一个子类只能有一个父类)或多层继承(一个子类可以继承自另一个子类,形成继承链)。

package oop_useInterface;

public abstract class Animal {
	private String name;
	private int age;

	public Animal() {
	}

	public Animal(String name, int age) {

		this.name = name;
		this.age = age;
	}

/*此处省略getter() setter()方法*/

	public abstract void eat(String age);
}

Dog继承了Animal的字段并重写了eat这个抽象方法实现了具体的能力:

package oop_useInterface;

public class Dog extends Animal implements Swim{

	public Dog() {
		super();
	}

	public Dog(String  name, int age) {
		super(name, age);
	}

	public void swim(int age) {
		System.out.println("DOg Swim");
	}

	@Override
	public void eat(String a) {
	System.out.println("DOG EAT");
	}

}

2.> 类和接口之间的实现关系:

实现关系,可单多实现,还可以在继承一个类的同时实现多个接口。
	使类必须实现接口中定义的方法

接口是一种规范,它定义了一组方法的签名(方法名、参数类型和返回类型),但没有具体的实现。类可以实现一个或多个接口,这意味着类需要提供接口中定义的所有方法的具体实现。实现关系是类与接口之间的关系,它强制类实现接口中定义的方法。这种关系使得类可以符合特定的接口标准,从而可以更容易地交互和替换。

public interface Swim {
	public abstract void swim(int age);
}

按照上方Dog类的implement的关键字,证明Dog接入了Swim这个接口中的swim方法,将其里面的抽象方法重写,实现了Dog类拥有swim方法。
3>. 接口和接口之间的继承关系:

继承关系:可单可多;实现类需要重写所有的抽象方法;
	新接口继承已有接口的方法签名:

接口之间也可以存在继承关系,类似于类之间的继承关系。一个接口可以继承自一个或多个接口,这样新的接口就会继承已有接口的方法签名。实现类需要重写所有的抽象方法。这种继承关系允许你在新接口中定义更多的方法,并且同时继承了父接口中的方法签名。如果一个类实现了一个继承自其他接口的接口,那么它需要提供所有继承的接口方法的具体实现。

// 定义基础接口 Shape
interface Shape {
    void draw();
}

// 定义继承自 Shape 的 Resizable 接口
interface Resizable extends Shape {
    void resize(int percentage);
}

// 定义继承自 Resizable 的 Drawable 接口
interface Drawable extends Resizable {
    void colorize(String color);
}

在这里插入图片描述

< 2 >接口中的成员:

[ 1 ] 成员变量:

接口中有常量,且只能是常量。这就意味着常量在接口中只能被默认的修饰为public static final这意味着它们是全局可访问的常量。这些常量通常用于定义接口相关的常量值,且不可被更改。
在这里插入图片描述

[ 2 ] 构造方法 — >是不存在的

接口是不存在构造方法的

[ 3 ] 成员方法:

【 1 】JDK7 :接口只能定义抽象方法

当接口内的规则(指新增抽象方法)一改增,导致下面的实现类需要随之改增。

原因:实现类需要重写所有的抽象方法

在 JDK 8 之后的版本中,Java 引入了默认方法(default methods)和静态方法(static methods)的概念,允许在接口中提供方法的默认实现,但这也是有限制的,而且默认方法引入了一些新的问题和考虑事项。

【 2 】JDK8:接口可以有定义的方法体(默认,静态)

接口的能力升级:实现类无需立即进行修改,只需遵循某些规则并进行重写即可。

(1)允许接口定义默认方法,default修饰

格式L:public default	返回值类型 方法名(参数列表){ 
实例L:public default void show(){}
	**注意事项
	[1]默认方法不是抽象方法,不强制被重写;如果被重写,徐去掉default关键字
	[2]public可以省略,default不能省略,如果省略Java会将其当做抽象方法
	[3]如果实现多个接口,多个接口存在相同名字的默认方法,子类就必须对改方法进行重写

是

Java类和多接口的时候,若多接口中存在重名的方法,而优先类中没有复写,用eclisp的快捷方式为什么只有靠近implement的接口中的方法+解决办法

如果一个类实现了多个接口,而这些接口中有重名方法,但类本身没有复写这个方法,Eclipse通常会根据"implement"关键字后面的接口的顺序,选择第一个接口中的方法作为默认方法。
在这里插入图片描述

解决办法:

(1)手写自己想要的方式
(2)放在波浪线上,表示有一个或多个建议的操作。- ->这个仅仅是继承了接口中的default默认方法
在这里插入图片描述

(2)允许接口中定义定义静态方法,需要用static修饰

格式L:public static 返回值类型 方法名(参数列表){}
实例L:public static void show(){}
	**注意事项
	[1]静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
	[2]public可以省略,static不能省略。如果省略Java会将其当做抽象方法
	[3]静态方法不可重写
再次理解重写:子类把父类继承下来的虚方法表里面的方法覆盖的过程。
	静态的,私有的,最终的不会添加到方法表的。	

在这里插入图片描述
Inter

package oop_useInterface5_JDK8_NewMethod2;

public interface Inter {
	
	public abstract void method();
	public static void show() {
		System.out.println("Inter-static Method");
	}
}

InterImpl

package oop_useInterface5_JDK8_NewMethod2;

public class InterImpl implements Inter{

	@Override
	public void method() {
		System.out.println("InterImpl-overideMethod");
	}
	//实现类不可被重写,需要去掉Override

	//不叫重写,只是一个重名的方法
	public  static void show() {
		System.out.println("InterImpl-static Method");
	}
}

Test

package oop_useInterface5_JDK8_NewMethod2;

public class Test {

	public static void main(String[] args) {
//下面只是重名的方法:		
	//接口中静态方法
		Inter.show();
		
	//实现了的静态方法
		InterImpl.show();
	}
	
	//再次理解重写:	子类把父类继承下来的虚方法表里面的方法覆盖的过程。
		//静态的,私有的,最终的不会添加到方法表的。
}

在这里插入图片描述

【 3 】JDK9:接口有私有方法:

JDK9以前,一个接口在两个default方法,如果有相同的表述,可以采用在写一个default方法抽取出来,如何调用对应方法但抽取是为本代码访问,不想被外类使用,所以要变访问修饰符 -->抽离方法

[1]普通的私有方法,给default默认方法服务(普通的私有方法,给默认方法服务的。default删去)
		格式1L:private 返回值类型 方法名(参数列表){}
		实例1L:private void show(){}


[2]静态的使用方法,给static静态方法服务(静态的私有方法,给静态方法服务的)
		格式2L:private static 返回值类型 方法名(参数列表){}
		实例2L:private static void method(){}

Inter1

package oop_useInterface5_JDK9_New_PrivateMethod;

public interface Inter1 {
	public static  void showA() {
		System.out.println("ShowA--run");
		RunB();
	}
	
	public default void showB() {
		System.out.println("ShowB--run");
		RunA();
	}
	
//	public default void Run() {
//		System.out.println("Running");
//	}
	//普通的私有方法,给默认方法服务的。default删去
	private void RunA() {
		System.out.println("Running");
	}
	
	//静态的私有方法,给静态方法服务的
	private static void RunB () {
		System.out.println("Running");
	}
}

main方法

package oop_useInterface5_JDK9_New_PrivateMethod;

public class Testsss {
	public static void main(String[] args) {

	 Inter1.showA(); // 调用静态的接口方法
     
	 Inter1 inter1 = new Inter1Impl();
     inter1.showB(); // 调用默认的接口方法
 }
}
class Inter1Impl implements Inter1 {
	@Override
	public void showB() {
		// TODO 自动生成的方法存根
		Inter1.super.showB();
	}
    // 实现类不需要实现私有方法
}

(1)为什么showB需创建对象,而A的却不用

静态方法是与接口本身关联的,与实现类无关,因此可以通过接口名称来直接调用。这就是为什么您可以使用 Inter1.showA() 这样的方式调用 showA 方法,无需创建实现类的对象。

默认方法是为了向已有的接口添加新方法而引入的,这样可以保证已有的类库仍然能够正常工作。因此,默认方法在实现类中必须被实现,而且需要通过实现类的对象来调用,因为默认方法是实例方法,与特定的实例相关联。

(2)普通的私有方法,给default默认方法服务(普通的私有方法,给默认方法服务的。default删去)

如果不去掉default:

Illegal combination of modifiers for the private interface method RunA; additionally only one of static and strictfp is permitted
在这里插入图片描述
当去除default就可以为其服务
在这里插入图片描述

< 3 >对比代码

[ 1 ] 没有抽象方法的抽象实现类:

虽然是抽象实现类:接口中的没有声明是默认的、静态的、私有的就会被认为是抽象的方法,抽象的方法一定要去重写,赋予具体的实现过程。

interface MyInterface {
    void method1(); // 接口中的方法

    void method2();
}

class MyConcreteClass  implements MyInterface {
    public void method1() {
      System.out.println("执行 method1");
  }
    public void method2() {
        System.out.println("执行 method2");
    }
}

public class sadasd {
    public static void main(String[] args) {
        MyConcreteClass myObject = new MyConcreteClass();

        myObject.method1(); // 输出:执行 method1
        myObject.method2(); // 输出:执行 method2
    }
}

[ 2 ] 实现类是抽象类的类

public interface MyInterface {
    void method1(); // 接口中的方法

    void method2();
}

public abstract class MyAbstractClass implements MyInterface {
    public void method1() {
        System.out.println("执行 method1");
    }

    // method2没有提供具体实现
}

public class MyConcreteClass extends MyAbstractClass {
    public void method2() {
        System.out.println("执行 method2");
    }
}

public class Main {
    public static void main(String[] args) {
        MyConcreteClass myObject = new MyConcreteClass();

        myObject.method1(); // 输出:执行 method1
        myObject.method2(); // 输出:执行 method2
    }
}

一定要实现其中的抽象方法
The type MyConcreteClass must implement the inherited abstract method MyInterface.method2()
在这里插入图片描述

< 4 >InterApply:

public interface Method{}
	
	public void show(Method的接口 c){}
		即:接口类型 x = new 实现类对象
		(编译看左边,运行看右边)
  1. 接口代表规则,是行为的抽象
    接口是 Java 中用于定义一组方法签名(即方法名称、参数列表和返回类型)的规范。它们不包含方法的具体实现,只声明了方法的签名。类可以实现一个或多个接口,从而表明它们将遵循这些接口所定义的规则,也就是行为。

  2. 方法的参数是接口时,可以传递接口所有实现类的对象:–>接口多态
    当一个方法的参数是接口类型时,可以传递实现了该接口的任何类的对象作为参数。这体现了多态的概念,即你可以在运行时传递不同的对象,实现不同的行为,但是方法的定义只关心接口所规定的方法签名。

  3. 接口和抽象类不可以实例化

    创建实现了接口的类的对象,或者从抽象类派生出具体的子类,然后通过这些对象进行实例化。这也是多态的体现。
    

    是指不能直接通过 new 关键字实例化接口或抽象类,但是可以传递引用,实现多态。意思是不能直接使用new 接口名new 抽象类名·来创建对象。
    但可以通过类实现接口或继承抽象类,并创建实现类的对象。这些实现类可以通过接口引用来实现多态,从而在不同的上下文中使用不同的实现。

  4. 编译时和运行时
    在Java 中,有一个重要的原则是“编译看左边,运行看右边”。这指的是,在编译阶段编译器只关注左边(变量的声明类型),而在运行时,实际执行的方法是根据右边(对象的实际类型)确定的。

代码举例[ 1 ]:

package com.example.shapes;

public interface Shape {
    double calculateArea();
}
package com.example.shapes;

public class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return this.radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}
package com.example.shapes;

public class Rectangle implements Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}
package com.example.shapes;

public class AreaCalculator {
    public void printArea(Shape shape) {
        double area = shape.calculateArea();
        System.out.println("Area: " + area);
    }
}
package com.example.shapes;

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);
        
        if (circle instanceof Circle) {
            ((Circle) circle).setRadius(123);
            double radius = ((Circle) circle).getRadius();
            System.out.println("Circle Radius: " + radius);
        } else {
            System.out.println("circle is not an instance of Circle");
        }
        
        AreaCalculator calculator = new AreaCalculator();
        calculator.printArea(circle);     // Output: Area: 78.53981633974483
        calculator.printArea(rectangle);  // Output: Area: 24.0
    }
}

分析代码:

  1. 接口代表规则,是行为的抽象
    在代码中,Shape 接口就是一个很好的示例。它定义了一个名为 calculateArea() 的方法,表达了所有实现了该接口的类应该提供计算面积的行为。CircleRectangle 类实现了 Shape 接口,表明它们都遵循了这一规则,并提供了自己的面积计算方法。

  2. 方法的参数是接口时,可以传递接口所有实现类的对象
    AreaCalculator 类中的 printArea(Shape shape) 方法就是这个例子。它的参数是一个接口类型 Shape,但你可以传递实现了 Shape 接口的任何类的对象,如在 main 方法中所示。这允许你传递不同类型的图形(比如 CircleRectangle)作为参数,但方法的定义只关心 Shape 接口的规范。

  3. 接口和抽象类不可以实例化
    接口 Shape 是无法直接实例化的,而 CircleRectangle 作为它的实现类,可以通过 new 关键字实例化。在 main 方法中,你使用了多态来创建一个 Circle 对象和一个 Rectangle 对象,并将它们赋给了 Shape 类型的引用变量 circlerectangle

为什么在main方法中必须强转circle从Shape到Circle的时候setRadius才能用:

在代码中,在main方法中创建了一个Shape类型的对象 circle,并且将它实际实例化为了一个Circle对象。然而,由于你将其声明为Shape类型,编译器只知道它是一个实现了Shape接口的对象,并没有直接访问Circle类中特有的方法和属性的权限。

当你尝试在circle对象上调用setRadius方法时,编译器无法确定这个方法是否存在于Shape接口中,因为在Shape接口中并没有定义这个方法。因此,编译器会报错,提示Shape接口中没有setRadius方法。

为了解决这个问题,可以使用强制类型转换 (Circle) circlecircle 对象转换为 Circle 类型。这样编译器就知道你希望将它视为 Circle 类型,可以调用 Circle 类中定义的方法和属性。

然而,需要注意的是,强制类型转换存在一些风险,因为你需要确保对象实际上是你期望的类型。如果你尝试将一个不是 Circle 类型的对象进行强制转换,会在运行时抛出 ClassCastException

在你的代码中,由于你在 main 方法中已经创建了一个 Circle 对象,并将其赋给了 circle 变量,因此强制类型转换是安全的,但是通常最好在进行强制类型转换之前使用 instanceof 进行类型检查,以避免可能的异常情况。你在代码中使用了 instanceof 来检查 circle 是否是 Circle 类型的实例,然后才进行强制类型转换,这是一个良好的实践。

总结一下,在 main 方法中使用强制类型转换是为了获得更多关于对象的类型信息,从而让编译器识别并允许访问特定类型的方法和属性。但是要注意类型转换的安全性,避免出现运行时异常。

代码举例[ 2 ]:

// 定义接口
public interface Animal {
    void makeSound();
}

// 实现接口的 Dog 类
public class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

// 实现接口的 Cat 类
public class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

// 主类
public class Main {
    // 方法参数是接口类型,可以接受实现了该接口的任何类的对象
    public void animalSound(Animal animal) {
        animal.makeSound();
    }

    public static void main(String[] args) {
        Main main = new Main();
        
        Animal dog = new Dog(); // 实现类对象通过接口引用
        Animal cat = new Cat(); // 实现类对象通过接口引用
        
        main.animalSound(dog); // 编译时 Animal,运行时 Dog 的 makeSound
        main.animalSound(cat); // 编译时 Animal,运行时 Cat 的 makeSound
    }
}

分析:

多态是面向对象编程的一个重要特性,它允许你使用基类或接口类型的引用来引用派生类或实现类的对象,从而在运行时根据对象的实际类型来决定调用哪个方法。在这个示例中,Animal 是一个接口,DogCat 是实现了 Animal 接口的类。通过将 DogCat 的实例赋值给 Animal 类型的引用,你可以在 animalSound 方法中使用多态,根据实际的对象类型来调用正确的 makeSound 方法。

这种方法使得代码更加灵活和可扩展,因为你可以添加更多实现了 Animal 接口的类,而不需要修改 animalSound 方法的代码,从而实现了代码的开闭原则。

< 5 > 适配器模式(Adapter Pattern):

当一个接口中的抽象方法过多,但只需要使用其中一部分时候采用【相当于一个方法表】
	
步骤:	
	编写中间类: 接口名Adapter 实现对应接口
		对接口中的抽象方法进行空实现
	让真正的实现类继承中间类,并重写需要的方法
	为了避免其他类创建适配器类的对象,中间的适配器类用abstract修饰
细节:继承的实现类还有多个继承,可以采取间接继承【因为Java没有多继承的】

代码1

下面是一个简单的示例代码来演示适配器模式的用法。在这个示例中,我们使用适配器模式来适配一个已有的LegacyRectangle类(旧接口)到一个新的Rectangle接口(新接口),只需要使用Rectangle接口的一部分方法。

// 定义新的目标接口
interface Rectangle {
    void draw();
    void resize();
}

// 旧的LegacyRectangle类(旧接口)
class LegacyRectangle {
    void oldDraw() {
        System.out.println("LegacyRectangle: Drawing");
    }

    void oldResize() {
        System.out.println("LegacyRectangle: Resizing");
    }
}

// 适配器类,将LegacyRectangle适配到Rectangle接口
abstract class RectangleAdapter implements Rectangle {
    @Override
    public void draw() {
        // 空实现,可以在子类中选择实现
    }

    @Override
    public void resize() {
        // 空实现,可以在子类中选择实现
    }
}

// 实际的适配器,继承RectangleAdapter并实现需要的方法
class LegacyRectangleAdapter extends RectangleAdapter {
    private LegacyRectangle legacyRectangle;

    public LegacyRectangleAdapter(LegacyRectangle legacyRectangle) {
        this.legacyRectangle = legacyRectangle;
    }

    @Override
    public void draw() {
        legacyRectangle.oldDraw();
    }

    @Override
    public void resize() {
        legacyRectangle.oldResize();
    }
}

public class AdapterPatternExample {
    public static void main(String[] args) {
        // 使用适配器来调用LegacyRectangle的方法,看起来像是调用Rectangle接口的方法
        LegacyRectangle legacyRectangle = new LegacyRectangle();
        Rectangle adapter = new LegacyRectangleAdapter(legacyRectangle);

        adapter.draw();   // 实际调用LegacyRectangle的oldDraw方法
        adapter.resize(); // 实际调用LegacyRectangle的oldResize方法
    }
}

在这个示例中,LegacyRectangle是旧接口,Rectangle是新接口。我们创建了一个RectangleAdapter作为适配器抽象类,然后创建了一个具体的适配器类LegacyRectangleAdapter,它继承自RectangleAdapter并将LegacyRectangle适配到了Rectangle接口。在main方法中,我们可以看到通过适配器来调用LegacyRectangle的方法,实际上调用的是旧接口的方法,但通过适配器,它们看起来像是在调用新接口的方法。

代码2:

// 定义原始接口
interface Shape {
    void draw();
}

// 定义更新后的接口
interface UpdatedShape {
    void draw();

    void resize();
}

// 中间适配器类,用 abstract 修饰,提供空实现
abstract class ShapeAdapter implements UpdatedShape {
    @Override
    public void draw() {
        // 空实现
    }

    @Override
    public void resize() {
        // 空实现
    }
}

// 实现类继承适配器类,只需要重写需要的方法
class CircleAdapter extends ShapeAdapter {
    private Shape adaptedShape;

    public CircleAdapter(Shape shape) {
        this.adaptedShape = shape;
    }

    @Override
    public void draw() {
        adaptedShape.draw();
    }
}

// 圆形类实现原始接口
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        UpdatedShape updatedCircle = new CircleAdapter(circle);

        updatedCircle.draw(); // 调用原始方法
        updatedCircle.resize(); // 调用新增方法,空实现
    }
}

这个新的接口就是说是这个旧的就接口的一种接口升级。然后又因为这个接口中的抽象方法必须在实现类中进行重写,使用需要一个适配器重写这个新的接口中的方法。
其中的自己适配器类是为了扩展新的方法,最后到达这个继承下来的真正的适配器,就完成了新的接口内部方法的复写

Shape circle = new Circle();
UpdatedShape updatedCircle = new CircleAdapter(circle);
创建实现了接口的类的对象,或者从抽象类派生出具体的子类,然后通过这些对象进行实例化。这也是多态的体现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ES6中promise的使用

ES6中promise的使用 本文目录 ES6中promise的使用基础介绍箭头函数function函数状态 原型方法Promise.prototype.then()Promise.prototype.catch() 静态方法Promise.all()Promise.race()Promise.any() 链式回调 基础介绍 官网&#xff1a;https://promisesaplus.com/ window.…

k8s 安装istio (一)

前置条件 已经完成 K8S安装过程十&#xff1a;Kubernetes CNI插件与CoreDNS服务部署 部署 istio 服务网格与 Ingress 服务用到了 helm 与 kubectl 这两个命令行工具&#xff0c;这个命令行工具依赖 ~/.kube/config 这个配置文件&#xff0c;目前只在 kubernetes master 节点中…

【IO进程线程】使用标准IO函数完成用户的登录和注册

1 实现登录功能 自定义一个usr.txt&#xff0c;先手动输入其账户密码。 格式&#xff1a;账户 密码 例&#xff1a; zhangsan 12345 lisi abcde wangwu abc123 需求如下&#xff1a; 1. 从终端获取账户密码&#xff0c;与文件中的账户密码比较&#xff1b; 2. 若终端输入的账户…

SpeedBI数据可视化工具:丰富图表,提高报表易读性

数据可视化工具一大作用就是能把复杂数据可视化、直观化&#xff0c;更容易看懂&#xff0c;也就更容易实现以数据驱动业务管理升级&#xff0c;因此一般的数据可视化工具都会提供大量图形化的数据可视化图表&#xff0c;以提高报表的易懂性&#xff0c;更好地服务企业运营决策…

websocket和uni-app里使用websocket

一、HTTP是无状态协议 特点&#xff1a; 1、浏览器发送请求时&#xff0c;浏览器和服务器会建立一个连接。完成请求和响应。在http1.0之前&#xff0c;每次请求响应完毕后&#xff0c;会立即断开连接。在http1.1之后&#xff0c;当前网页的所有请求响应完毕后&#xff0c;才断…

prometheus + grafana进行服务器资源监控

在性能测试中&#xff0c;服务器资源是值得关注一项内容&#xff0c;目前&#xff0c;市面上已经有很多的服务器资 源监控方法和各种不同的监控工具&#xff0c;方便在各个项目中使用。 但是&#xff0c;在性能测试中&#xff0c;究竟哪些指标值得被关注呢&#xff1f; 监控有…

ctfshow-web13 文件上传

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先看到是一个上传页面&#xff0c;测试其他无果&#xff0c;遂进行目录遍历&#xff0c;发现upload.php.bak文件 可以看到这里的限制条件&#xff0c;大小&#xff0c;以及内容&#xff0c;这里可以使用.use…

渗透测试漏洞原理之---【XSS 跨站脚本攻击】

文章目录 1、跨站 脚本攻击1.1、漏洞描述1.2、漏洞原理1.3、漏洞危害1.4、漏洞验证1.5、漏洞分类1.5.1、反射性XSS1.5.2、存储型XSS1.5.3、DOM型XSS 2、XSS攻防2.1、XSS构造2.1.1、利用<>2.1.2、JavaScript伪协议2.1.3、时间响应 2.2、XSS变形方式2.2.1、大小写转换2.2.2…

基于Red Hat Enterprise Linux 7操作系统的PostgresSql15的备份恢复(实践笔记)

零、前言 本文是基于阿里云ECS服务器进行的实践操作&#xff0c;操作系统版本&#xff1a;Red Hat Enterprise Linux 7 PG数据库版本&#xff1a;PostgresSql 15 PG安装方式&#xff1a;yum 由于本人新接触pg数据&#xff0c;本次也是出于好奇&#xff0c;就对pg数据库的pg_du…

回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BES-ELM秃鹰搜索优化算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效…

软考A计划-系统集成项目管理工程师-小抄手册(共25章节)-下

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

谷歌面试-扔鸡蛋

今天想跟大家分享一个有意思的面试题&#xff0c;这让我再一次感叹思维的奇妙&#xff0c;接下来我们一起看看吧~ 首先来看看题目&#xff1a; 你有2颗鸡蛋&#xff0c;需要以最少的尝试次数来判断在100层的高楼上&#xff0c;哪一层楼是鸡蛋的安全层。 换句话说&#xff0c…

不同子网络中的通信过程

从输入www.baidu.com经历了什么 一、DNS&#xff08;网址->IP&#xff09; 二、ARP&#xff08;IP->MAC&#xff09; A->B&#xff1a;有数据发送&#xff0c;数据封装ip之后发现没有主机B的mac地址。然后ARP在本网段广播&#xff1a;检查目标地址和源地址是否在同一…

springboot源码编译问题

问题一 Could not find artifact org.springframework.boot:spring-boot-starter-parent:pom:2.2.5.RELEASE in nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public/) 意思是无法在阿里云的镜像仓库中找到资源 解决&#xff1a;将配置的镜像删除即可&#…

【SkyWalking】分布式服务追踪与调用链系统

1、基本介绍 SkyWalking是一个开源的观测平台&#xff0c;官网&#xff1a;Apache SkyWalking&#xff1b; 可监控&#xff1a;分布式追踪调用链 、jvm内存变化、监控报警、查看服务器基本配置信息。 2、SkyWalking架构原理 在整个skywalking的系统中&#xff0c;有三个角色&am…

4.18 TCP 和 UDP 可以使用同一个端口吗?

目录 TCP 和 UDP 可以同时绑定相同的端口吗&#xff1f; 多个 TCP 服务进程可以绑定同一个端口吗&#xff1f; 重启 TCP 服务进程时&#xff0c;为什么会有“Address in use”的报错信息&#xff1f; 重启 TCP 服务进程时&#xff0c;如何避免“Address in use”的报错信息…

【考研数学】线性代数第四章 —— 线性方程组(1,基本概念 | 基本定理 | 解的结构)

文章目录 引言一、线性方程组的基本概念与表达形式二、线性方程组解的基本定理三、线性方程组解的结构写在最后 引言 继向量的学习后&#xff0c;一鼓作气&#xff0c;把线性方程组也解决了去。O.O 一、线性方程组的基本概念与表达形式 方程组 称为 n n n 元齐次线性方程组…

Postman —— postman实现参数化

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数每…

Docker安装及Docker构建简易版Hadoop生态

一、首先在VM创建一个新的虚拟机将Docker安装好 更新系统&#xff1a;首先打开终端&#xff0c;更新系统包列表。 sudo apt-get update sudo apt-get upgrade下图是更新系统包截图 安装Docker&#xff1a;使用以下命令在Linux上安装Docker。 sudo apt-get install -y docker.i…

python爬虫实战零基础(3)——某云音乐

爬取某些云网页音乐&#xff0c;无需app 分析网页第二种方式批量爬取 声明&#xff1a;仅供参考学习&#xff0c;参考&#xff0c;若有不足&#xff0c;欢迎指正 你是不是遇到过这种情况&#xff0c;在pc端上音乐无法下载&#xff0c;必须下载客户端才能下载&#xff1f; 那么&…