类和对象(5)——抽象类和接口
目录
1. 抽象类
1.1 抽象类的概念
1.2 抽象类语法:abstract关键字
1.3 抽象类的特性
1.4 抽象类的作用
2. 接口
2.1 接口的概念
2.2 接口语法:interface关键字
2.3 接口的实现:implements关键字
2.4 接口的特性
2.5 实现多个接口
2.6 接口间的继承
2.7 接口的多态性
2.8 再谈instanceof
2.8.1 检查接口的实现
2.8.2 类型可见性问题
2.8.3 易混淆的可见性
3. 抽象类与接口的区别
1. 抽象类
1.1 抽象类的概念
在面向对象的概念中,所有的对象都是通过类来描绘的;但是反过来,并不是所有的类都是用来描绘对象的,如果 一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
- 抽象类是一种不能被实例化,只能用作其他类的父类的类。它通常用于定义一组具有共同特征和行为的子类的基础框架,这些共同特征和行为以抽象方法的形式呈现,子类需要提供这些抽象方法的具体实现。
1.2 抽象类语法:abstract关键字
那么在java语言中,抽象类要如何表示呢?
java提供了一个abstract关键字,被该关键字修饰的类就是抽象类。
抽象类的语法:
(其他修饰词) abstract class 抽象类名{
……
}
abstract除了可以修饰类,还可以修饰成员方法使其成为抽象方法。需要注意的是,抽象方法只能存在于抽象类当中
抽象方法的语法:
(其他修饰词) abstract class 抽象类名{
……
(其他修饰词) abstract 返回值类型 抽象方法名 (参数表); //抽象方法无具体实现
……
}
例如:
public abstract class Animal {private String name;private int age;//抽象方法abstract public void eat();
}
1.3 抽象类的特性
抽象类具有很多的特性和使用要求,我在下面一一列举出来。
1. 抽象类不能被直接实例化成对象。
以上面抽象类Animal为例:
其实这样的要求也很好理解,因为抽象类的产生就不是为了描述对象的,它也没有包含足够的信息来描绘一个具体的对象,必须由它的非抽象子类来实例化对象。
2. 抽象类被继承后,其子类要重写父类中的抽象方法;否则子类也必须设为抽象类,被abstract修饰。
子类Dog没有重写抽象方法,且没有设为抽象类而报错:
package demo3; //包名:demo3
//抽象父类Animal
public abstract class Animal {public String name;public int age;//抽象方法abstract public void eat();
}
//Dog类继承自抽象类
public class Dog extends Animal{public void bark(){System.out.println(name+"在汪汪叫");}
}
补充:非抽象子类需要重写的抽象方法都来自其直接父类的抽象方法。
假如有A、B、C三个类,A是B的直接父类,B是C的直接父类;A和B都是抽象类,C是普通类。如果B重写了A中的部分抽象方法,那么C要重写的抽象方法有 A剩下的抽象方法 和 B新增加的抽象方法。
例如:
//抽象类Animal
public abstract class Animal {public String name;//2个抽象方法abstract public void eat();abstract public void sleep();
}
//抽象类Dog
public abstract class Dog extends Animal{//重写了抽象方法eat()public void eat(){System.out.println(name+"在吃狗粮");}//新增1个抽象方法walk()abstract public void walk();
}
//普通类 柯基
public class Corgi extends Dog{//报错:没有重写抽象方法sleep()和walk()
}
这里Dog继承自Animal,所以Dog包含成员变量name、父类方法eat和sleep 以及自己新增的抽象方法walk。
又因为Dog重写了抽象方法eat,eat方法在Dog类已经不是抽象方法,所以Dog类中只有sleep和walk两个抽象方法。
由于非抽象子类需要重写的抽象方法都来自其直接父类的抽象方法,所以柯基Corgi类必须要重写sleep和walk这两个直接来自Dog类的抽象方法。
3. 抽象方法不能被private、final和static修饰,因为抽象方法要被子类重写。
4. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量。
5. 抽象类中不一定有抽象方法,但是抽象方法只能存在于抽象类当中。
无抽象方法的抽象类:
报错·含抽象方法的普通类:
1.4 抽象类的作用
抽象类本身不能被实例化,要想使用,只能创建该抽象类的子类。 然后让子类重写抽象类中的抽象方法。
有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?
确实如此. 但是使用抽象类相当于多了一重编译器的校验.
使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类 了, 使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.
很多语法存在的意义都是为了 "预防出错", 例如我们曾经用过的 final 也是类似. 创建的变量用户不去修改, 不 就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候, 让编译器及时提醒我们. 充分利用编译器的校验, 在实际开发中是非常有意义的
2. 接口
2.1 接口的概念
在现实生活中,接口的例子比比皆是,比如:笔记本上的USB口,电源插座等。
电脑侧面的USB口上,可以插:U盘、鼠标、键盘...所有符合USB协议的设备
电源插座的插孔上,可以插:电脑、电视机、电饭煲...所有符合规范的设备
通过上述例子可以看出:接口就是公共的行为规范标准。大家在实现时,只要符合规范标准,就可以通用。
我们知道,在编程上我们用类来描述对象,像电脑、鼠标、U盘这些对象都可以用类来描述。自然的,我们也会有编程上的接口。
在Java中,接口可以看成是多个类的公共规范,也是一种引用数据类型。
2.2 接口语法:interface关键字
接口的语法格式 与 类的语法格式类似,将 class关键字 换成 interface关键字,就定义了一个接口。
接口的语法格式:
(其他限定词) interface 接口名{
……
}
例如:写一个图形接口,规范是要实现画图形方法draw。
public interface IShape {void draw(); //画一个图形
}
注意:
- 接口的命名采用大驼峰命名法。
- 接口的命名一般以大写字母 I 开头,它的后一个字母也要大写。
2.3 接口的实现:implements关键字
接口不能直接使用,必须要有一个"实现类"来"实现"该接口。而实现指的是:重写接口中的所有抽象方法。(在接口中定义的方法都是抽象方法)
在java中,提供一个关键字implements来让我们完成对接口的实现
实现的语法:
(其他限定词) class 类名 implements 接口名{
……
//重写的接口方法
}
例如:
//接口
public interface IShape {void draw(); //画一个图形
}//实现类
public class Flower implements IShape{@Overridepublic void draw() {System.out.println("画一朵花……");}
}//测试
public class Test {public static void main(String[] args) {IShape iShape = new Flower();//向上转型iShape.draw();}
}
可以看到,实现了接口,可以通过向上转型的方式来调用接口函数,这是接口多态性的一种体现。
2.4 接口的特性
1. 与抽象类一样,接口虽是一种引用类型,但是不能直接new接口的对象。
例如:
2. 接口中的成员变量都是被“ public static final ”修饰的。
也就是说,接口中的成员变量是一种静态全局常量。无论是无修饰(default),还是显式用public修饰、static修饰或final修饰,它们最终都是由“ public static final ”共同修饰。
以下面的USB接口为例:
public interface USB {double brand = 10;
}
3. 接口中的方法都是由“ public abstract ”修饰。
无论是无修饰(default),还是显式用public修饰或abstract修饰,接口方法都是由“ public abstract ”共同修饰。也就是说接口方法都是公共的抽象方法,必须要求实现类进行方法重写,这体现了接口作为公共规范的作用。
例如:
// 接口IShape
// Flower类
Flower类没有重写IShape接口的draw方法,由于接口方法都是抽象的,所以会报错。
补充:如果实现类没有重写接口的所有抽象方法,那么该实现类要设为抽象类。
4. 由于接口的变量和方法都有固定的修饰符修饰,所以不能用其他修饰符 修饰接口的变量和方法。(比如private、protected)
错误例子:
补充:接口的变量和方法都有默认修饰符,一般建议接口的变量和方法前面都不写任何修饰符。
5. 接口中不能有静态代码块、动态代码块 和 构造方法。
静态代码块一般用来初始化静态变量,动态代码块和构造方法一般用来初始化成员变量,但是接口中的变量都是常量,不能修改。
错误例子:
public interface USB {int BRAND = 10;static {//静态代码块}{//实例代码块}USB(int brand){BRAND = brand;}
}
6. 实现类重写接口方法时,重写的方法的包访问权限不能比接口方法的权限要低。即:不能是无修饰词(default)、不能是protected、不能是private。
例如:
【补充:其实 实现类的重写方法的访问权限在一种情况可以是无修饰词(default)的,这种情况我在第8点说】
7(小知识). 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class。
8(拓展). 从Java8版本开始,接口中可以定义default方法(默认方法)。它允许在接口中为方法提供默认的实现。
default方法在接口中的定义方式:
- 显示使用default关键字:在接口的方法签名前使用
default
关键字来定义一个默认方法。例如,default void methodName() {...}
。- 包含方法体:与接口中的抽象方法不同,默认方法是具体的方法实现,需要在接口中给出方法的具体代码逻辑。
【注意】: 接口方法被default修饰后,就不能再被final和static修饰。
例如:
//图形·接口
public interface IShape {//抽象方法void draw1();//默认方法default void draw2(){System.out.println("画两次图形");}
}
//圆形·类 :只重写抽象方法
public class Circle implements IShape{@Overridepublic void draw1() {System.out.println("画一个圆……");}
}
//花形·类:抽象方法和默认方法都重写了
public class Flower implements IShape{@Overridepublic void draw1() {System.out.println("画一朵花……");}@Overridepublic void draw2() {System.out.println("画两朵花");}
}public class Test {public static void main(String[] args) {Circle circle = new Circle();circle.draw1();circle.draw2(); //会使用接口的默认方法System.out.println("============================");Flower flower = new Flower();flower.draw1();flower.draw2();}
}
【这里的第8点特性属于拓展内容,了解即可】
2.5 实现多个接口
java中没有多继承,即一个子类不能继承自多个父类,但是一个类可以实现多个接口。
语法格式:(所有的接口都跟在implements的后面,每个接口之间用逗号隔开)
【无继承】
class 实现类 implements 接口1,接口2,……,接口K{
…… //实现类的成员
}
【有继承】(只能有一个父类) (“继承extends”要在“实现implements”前面)
class 实现类 extends 父类名称 implements 接口1,接口2,……,接口K{
…… //实现类的成员
}
下面演示如何用接口和继承来表示企鹅类:
先有父类Animal:
abstract public class Animal {protected String name;public Animal(String name){this.name = name;}
}
另外我们再提供一组接口, 分别表示 "会飞的", "会跑的", "会游泳的":
interface IFlying {void fly();}interface IRunning {void run();}interface ISwimming {void swim();}
最后我们创建具体的动物——企鹅类(企鹅既能在路上走,也能在水中游)
public class Penguin extends Animal implements IRunning,ISwimming{public Penguin(String name) {super(name);}@Overridepublic void run() {System.out.println(name+"用两只脚走路");}@Overridepublic void swim() {System.out.println(name+"用两只翅膀游泳");}
}
tips:在IDEA中使用 ctrl + i 可快速实现接口。
2.6 接口间的继承
类与类之间可以有继承关系,那接口与接口之间可以有继承关系吗?
接口与接口之间可以有继承关系,而且接口可以多继承,即一个接口可以继承自多个接口。
语法格式:(继承语法是extends,每个父接口之间用逗号隔开)
interface 子接口 extends 父接口1,父接口2,……,父接口k{
……
}
青蛙是两栖动物,我们用接口间的继承可以这样表示:
interface IRunning {void run();}interface ISwimming {void swim();}// 两栖的动物:既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {}class Frog implements IAmphibious {...}
2.7 接口的多态性
当实现类实现了接口,那么它就可以向接口类型进行向上转型。这体现了接口的多态性。
接口不仅仅是一种规范标准,它还是一种引用类型,这样的设计提高了代码的可重复性。
【实现多个接口】
实现类实现了多个接口,那么被实现的接口都可以接收实现类的向上转型。
例如:
//接口
public interface ISwimming {void swim();
}public interface IRunning {void run();
}
//实现类
public class Penguin implements ISwimming,IRunning{@Overridepublic void swim() {System.out.println("企鹅游泳");}@Overridepublic void run() {System.out.println("企鹅走路");}
}public class Dog implements IRunning{@Overridepublic void run() {System.out.println("狗在奔跑");}
}//多态方法
public class Test {public static void swim(ISwimming iSwimming){ //ISwimming接口类型作为多态类型参数iSwimming.swim(); //方法会根据动态绑定来使用}public static void run(IRunning iRunning){ //IRunning接口类型作为多态类型参数iRunning.run();}public static void main(String[] args) {Penguin penguin = new Penguin();swim(penguin); //向上转型传参run(penguin);System.out.println("==============");Dog dog = new Dog();run(dog);}
}
这里的Penguin类实现了ISwimming接口和IRunning接口,所以swim方法和run方法可以完成对penguin的向上转型。
【接口间的继承】
如果子接口继承自父接口,而实现类“直接实现”的是子接口,那么父接口也可以接收实现类的向上转型。
例如:
//IAmphibious接口继承自上面的ISwimming、IRunning接口
public interface IAmphibious extends ISwimming,IRunning{}//Penguin类直接实现IAmphibious接口
public class Penguin implements IAmphibious{@Overridepublic void swim() {System.out.println("企鹅游泳");}@Overridepublic void run() {System.out.println("企鹅走路");}
}public class Test {public static void swim(ISwimming iSwimming){ //ISwimming接口类型作为多态类型参数iSwimming.swim(); }public static void run(IRunning iRunning){ //IRunning接口类型作为多态类型参数iRunning.run();}public static void main(String[] args) {Penguin penguin = new Penguin();swim(penguin); run(penguin);}
}
- Penguin类实现了Imphibious接口,所以Penguin可以向Imphibious转型。
- 而Imphibious继承自ISwimming接口和IRunning接口,所以Imphibious可以向ISwimming接口和IRunning接口转型。
- 于是乎Penguin可以向ISwimming接口和IRunning接口向上转型
【注意】
如果子接口继承自父接口,实现类直接实现的也是这个父接口,那么该实现类不能向子接口进行向上转型。
错误例子:
//父接口
public interface IRunning {void run();
}//子接口:表示爬行类的动物
public interface ICreeping extends IRunning{
}//实现类:蜥蜴
public class Lizard implements IRunning{@Overridepublic void run() {System.out.println("蜥蜴在快速爬行");}
}//用子接口ICreeping接收实现类Lizard
public class Test {public static void run(ICreeping iCreeping){ iCreeping.run();}public static void main(String[] args) {Lizard lizard = new Lizard();run(lizard); //报错:Lizard类型与ICreeping类型不兼容}
}
接口多态性与继承多态性的对比:
2.8 再谈instanceof
2.8.1 检查接口的实现
我在《类和对象(4)——多态》中讲解过instanceof关键字,当时说过“该关键字不仅能判断类,还能判断接口”。但当时还没学到接口,现在让我们看看instanceof对于接口的作用。
instanceof的作用:(对象 instanceof 类名/接口名)
- 对于类:检查对象是否是指定类型的实例,或该类型的子类实例。
- 对于接口:检查对象是否实现了指定接口,或该接口的父接口。
为什么instanceof检查类的时候,可以检查其子类,而在检查接口的时候,却是可以检查其父接口呢?
这就不得不说一下instanceof检查的实际用途了:
类和instanceof的用途:确保向下转型的安全,从而让子类实例变量接收向下转型后的父类实例变量,使用子类特有的功能。
接口和instanceof的用途:确保对象具有某类多态行为,从而调用该多态方法。
类的举例和解析:
abstract public class Animal {public String name;public Animal(String name){this.name = name;}
}public class Dog extends Animal{public Dog(String name) {super(name);}public void eat(){System.out.println(super.name+"在吃狗粮");}
}public class Corge extends Dog{public Corge(String name) {super(name);}public void eat(){System.out.println(name+"在吃科技合成肉");}
}public class Test {public static void main(String[] args) {Animal animal1 = new Dog("小狗");if (animal1 instanceof Dog){ //检查为Dog类的实例Dog dog = (Dog) animal1;dog.eat();}Animal animal2 = new Corge("小柯基");if(animal2 instanceof Dog){ //检查为Dog类的子类实例Dog dog = (Dog) animal2;dog.eat();}}
}
- Dog类和Corge类都有自己特有的eat方法。
- 在animal1中,由于对象的本质是Dog类的实例,故可以安全地将animal1向下转型成Dog类。
- 在animal2中,虽然对象的本质是Corge类的实例,但由于Corge类是Dog类的子类(即Corge类可以向上转型成Dog类),所以它也可以安全地将animal2向下转型成Dog类。
- 这就解释了:为什么instanceof能检查指定类型的子类。
接口的举例和解析:
//父接口
public interface IRunning {void run();
}
public interface ISwimming {void swim();
}//子接口
public interface IAmphibious extends ISwimming,IRunning{}//实现类
public class Penguin extends Animal implements IAmphibious{@Overridepublic void swim() {System.out.println("企鹅游泳");}@Overridepublic void run() {System.out.println("企鹅走路");}
}//多态方法
public class Test {public static void run(IRunning iRunning){iRunning.run();}public static void main(String[] args) {Animal animal = new Penguin(); //向上转型if(animal instanceof IAmphibious){ 检查到指定接口的父接口的run行为run( (IAmphibious)animal ); //此时调用的是Test类中的多态方法run//或写成((IAmphibious)animal).run(); 此时调用的是自己的重写方法run}if(animal instanceof IRunning){ 检查指定接口run((IRunning) animal);//或写成((IRunning)animal).run();}}
}
- 子接口继承自多个父接口,实现类直接实现子接口 就相当于是 把所有父接口的行为都实现了一遍,那自然可以使用 以父接口类型为参数类型的多态方法。
- 这解释了:为什么instanceof能检查指定接口的父接口。
小结:
2.8.2 类型可见性问题
如果我们将上面接口例子中Test类(含多态方法的那个)修改成下面这样会发生什么:
可以发现,我们把强制类型转换用的“(IAmphibious)”去掉后居然报错了。这是编译时类型对成员可见性的限制惹的祸。
要明白 “编译时类型对成员可见性的限制”,我们必需先了解编译时类型和运行时类型的概念。
编译时类型(也称 声明类型)
- 变量在代码中声明的类型。(如" Parent parent;",此时实例变量parent的数据类型Parent就是编译时类型)(编译时类型也包括基础类型,如int、double)
- 编译器仅根据此类型检查可访问的成员变量和方法。
运行时类型(也称 实际类型)
- 对象实际所属的类型。(如“ new Child() ”)
- 运行时动态决定,但编译时不可见。
当用编译时类型的变量 访问 运行时类型的特有成员时,编译器检查发现该声明类型不具有访问特有成员的能力,直接触发了编译错误。这就是编译时类型对可见性的限制。
强制转换的作用
强制转换的本质是 告诉编译器,请按强转类型检查成员。编译器接受新的编译时类型,从而允许访问该类型定义的成员。运行时验证
强制转换可能在运行时失败(如 强转类型 与 对象实际类型 不符),因此需配合instanceof
提前检查类型安全。
2.8.3 易混淆的可见性
上述发生的编译错误属于类型可见性的问题,而不是权限的问题。
成员可见性:
- 在java中,权限指的就是各种访问修饰符。
- 而成员可见性的控制机制是访问修饰符(比如public、protected),为每个成员变量和方法赋予权限。
类可见性:
- 类可见性的控制机制也是访问修饰符,为类赋予访问权限。
- 成员可见性是 成员变量和成员方法 被访问修饰符修饰,共有4种权限;类可见性是 类 被访问修饰符修饰,顶级类只有public类或默认类(default)2种。
- 类的可见性是成员可见性的 前提。(如果顶级类是默认类,且内部所有成员都是public修饰的,那么不是同一个包的类就无法访问该顶级类及其所有成员。)
错误例子:
在包test1中有默认类Demo:
当我们在包test2中尝试使用Demo会报错:
包可见性:
- 包可见性 = default 权限 = 包访问权限 = 仅包内可见。
- 包可见性 包含于 成员可见性和类可见性当中。(包可见性是权限中的一种具体类型)
成员可见性和类的可见性通过访问修饰符定义,具体规则如下:
最终总结:
类可见性 和 成员可见性属于访问权限控制的同一维度(层级不同),且 类可见性是成员可见性的前提。
包可见性是访问权限控制中的一种具体类型(默认修饰符),属于成员可见性和类可见性的一部分。
类型可见性是独立于访问控制的另一维度,属于编译时类型系统的限制。
3. 抽象类与接口的区别
核心区别: 抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用(不必重写),而接口中不能包含普通方法(但是可以包含default方法),子类必须重写所有的抽象方法。
下面的表格是抽象类和接口不同的地方:
抽象类和接口的相同之处:
- 可以没有任何成员。(此时的接口被称作空接口或标记接口)
- 抽象方法不能被private、static、final修饰。
- 子类/实现类 重写方法的包访问权限不能更低。
- 子类/实现类 没有重写完所有的抽象方法时,必须设置为抽象类。
- 字节码文件的后缀都是.class。
本期分享完毕,感谢大家的支持Thanks♪(・ω・)ノ
相关文章:
类和对象(5)——抽象类和接口
目录 1. 抽象类 1.1 抽象类的概念 1.2 抽象类语法:abstract关键字 1.3 抽象类的特性 1.4 抽象类的作用 2. 接口 2.1 接口的概念 2.2 接口语法:interface关键字 2.3 接口的实现:implements关键字 2.4 接口的特性 2.5 实现多个接口 …...
海康摄像头IPV6模式,手动,自动,路由公告
海康摄像头DS-2DC7220IW-A 网络设置中的IPv6配置选项。IPv6是互联网协议(IP)的第六版,用于替代IPv4,提供更多的IP地址和改进的网络功能。图片中的选项允许用户选择如何配置设备的IPv6网络连接: 手动:用户可…...
LabVIEW与USB设备开发
开发一台USB设备并使用LabVIEW进行上位机开发,涉及底层驱动的编写、USB通信协议的实现以及LabVIEW与设备的接口设计。本文将详细介绍如何开发USB设备驱动、实现LabVIEW与USB设备的通信以及优化数据传输,帮助用户顺利完成项目开发。下面是一个详细的说明&…...
BY组态:工业自动化的未来,触手可及
在工业4.0的浪潮下,智能化、数字化已成为制造业发展的核心驱动力。作为工业自动化领域的重要工具,组态软件在实现设备监控、数据采集、流程控制等方面发挥着不可替代的作用。然而,传统的组态软件往往存在开发周期长、学习成本高、灵活性不足等…...
深入理解Python多进程编程 multiprocessing
深入理解Python多进程编程 multiprocessing flyfish Python 的 multiprocessing 模块允许创建多个进程,从而可以利用多核处理器的能力来并行执行任务。这意味着程序的不同部分可以在不同的CPU核心上同时运行,极大地提高了处理效率,特别是在…...
使用DeepSeek建立一个智能聊天机器人0.12
为了确保这段代码能够在Windows和Linux系统上都能正常运行,我考虑以下几个方面: 路径分隔符:在Windows和Linux中,文件路径的分隔符不同。Windows使用反斜杠(\),而Linux使用正斜杠(/)。我们可以使用 os.path.join 来处理路径,以确保跨平台兼容性。 消息框:tkinter.…...
基于VLC的Unity视频播放器(三)
关于UMP插件 UMP插件不更新了,我测试在Ubuntu24.04上编辑器和运行时都无法正常播放,在替换lib之后编辑器可以播放,但打包后不行……很奇怪 继续更新了一下UnityVLC 添加了对Linux的支持,勉强都可以播放了…… Win截图 Ubuntu2…...
每日一题——把数字翻译成字符串
把数字翻译成字符串 题目描述示例示例1示例2 题解动态规划代码实现复杂度分析 总结 题目描述 有一种将字母编码成数字的方式:‘a’->1, ‘b’->2, … , ‘z’->26。 现在给一串数字,返回有多少种可能的译码结果。 数据范围:字符串…...
基于状态观测器和物联网基础设施的智能电网高速孤岛检测
论文标题 中文标题: 基于状态观测器和物联网基础设施的智能电网高速孤岛检测 英文标题: High-Speed Islanding Detection in Smart Grids Using a State Observer and IoT Infrastructure 作者信息 Shahid Karim<sup>1,2, *</sup>, Prajo…...
FPGA的星辰大海
编者按 时下风头正盛的DeepSeek,正值喜好宏大叙事的米国大统领二次上岗就业,OpenAI、软银、甲骨文等宣布投资高达5000亿美元“星际之门”之际,对比尤为强烈。 某种程度上,,是低成本创新理念的直接落地。 包括来自开源社区的诸多赞誉是,并非体现技术有多“超越”,而是…...
【Black Mesa】黑山起源用服务器开服多人联机教程
1、登录服务器(百度莱卡云游戏面板) 进入控制面板后会出现正在安装的界面,安装大约10分钟(如长时间处于安装中请联系我们的客服人员) 2、修改端口 看到一下图片的界面时说明服务器已经安装完成,服务器需要…...
【学习笔记】深度学习网络-深度模型中的优化
作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程,深度学习领域研究生必读教材),开始深度学习领域学习,深入全面的理解深度学习的理论知识。 在之前的文章中介绍了深度学习中…...
java八股文之Redis
1.Rdis常见的使用场景 缓存分布式锁(redision,setnx)计数器保存token消息队列延迟队列 2.说明一下缓存雪崩,缓存穿透和缓存击穿以及解决方式 1.缓存雪崩 定义: 缓存雪崩指的是当大量的缓存数据同时失效,…...
ubuntu系统下KVM设置桥接网络(失败)
20250216 - 概述 因实验需求,需要设置KVM下的虚拟机采用桥接模式进行通信,这种方式将使虚拟机与主机类似使用同一网段的IP。实际上,为了实现这个功能,我已经在自己mac上VMware使用过,虚拟机获得了自己独立的IP。 但…...
CentOS 7操作系统部署KVM软件和创建虚拟机
CentOS 7.9操作系统部署KVM软件和配置指南,包括如何创建一个虚拟机。 步骤 1: 检查硬件支持 首先,确认您的CPU支持虚拟化技术,并且已在BIOS中启用: egrep -c (vmx|svm) /proc/cpuinfo 如果输出大于0,则表示支持虚拟…...
驱动开发系列38 - Linux Graphics 3D 绘制流程(一)- 创建画布
一:概述 当应用程序创建 OpenGL 上下文时,它通常需要申请帧缓冲(Framebuffer,即画布)。在 X11 体系下,应用程序不会直接向内核的 DRM 模块请求创建帧缓冲,而是通过 X 服务器进行申请。 虽然从技术上讲,应用程序可以直接使用 DRM 接口创建帧缓冲对象(BO),但为了将其与…...
Spring Boot过滤器链:从入门到精通
文章目录 一、过滤器链是什么?二、为什么需要过滤器链?三、Spring Boot中的过滤器链是如何工作的?(一)过滤器的生命周期(二)过滤器链的执行流程 四、如何在Spring Boot中定义自己的过滤器&#…...
QT 读写锁
一、概述 1、读写锁是一种线程同步机制,用于解决多线程环境下的读写竞争问题。 2、读写锁允许多个线程同时获取读锁(共享访问),但只允许一个线程获取写锁(独占访问)。 3、这种机制可以提高并发性能&…...
C++中的智能指针
智能指针总结 智能指针其作⽤是管理⼀个指针,避免程序员申请的空间在函数结束时忘记释放,造成内存泄漏这种情况滴发⽣。使⽤智能指针可以很⼤程度上的避免这个问题,因为智能指针就是⼀个类,当超出了类的作⽤域是,类会…...
IntelliJ IDEA 接入 AI 编程助手(Copilot、DeepSeek、GPT-4o Mini)
IntelliJ IDEA 接入 AI 编程助手(Copilot、DeepSeek、GPT-4o Mini) 📊 引言 近年来,AI 编程助手已成为开发者的高效工具,它们可以加速代码编写、优化代码结构,并提供智能提示。本文介绍如何在 IntelliJ I…...
【R语言】非参数检验
一、Mann-Whitney检验 在R语言中,Mann-Whitney U检验(也称为Wilcoxon秩和检验)用于比较两个独立样本的中位数是否存在显著差异。它是一种非参数检验,适用于数据不满足正态分布假设的情况。 1、独立样本 # 创建两个独立样本数据…...
PyTorch 源码学习:阅读经验 代码结构
分享自己在学习 PyTorch 源码时阅读过的资料。本文重点关注阅读 PyTorch 源码的经验和 PyTorch 的代码结构。因为 PyTorch 不同版本的源码实现有所不同,所以笔者在整理资料时尽可能按版本号升序,版本号见标题前[]。最新版本的源码实现还请查看 PyTorch 仓…...
04运维实用篇(D4_日志)
目录 一、简介 二、代码中使用日志工具记录日志 1. 操作步骤 步骤1:添加日志记录操作 步骤2:设置日志输出级别 步骤3:设置日志组 2. 知识小结 三、优化日志对象创建代码 1. 实例 2. 总结 四、日志输出格式控制 1. 实例 2. 总结 …...
Linux文件管理:硬链接与软链接
文章目录 1. 硬链接的设计目的(1)节省存储空间(2)提高文件管理效率(3)数据持久性(4)文件系统的自然特性 2. 软链接的设计目的**(1)跨文件系统引用****&#x…...
【零基础学Mysql】常用函数讲解,提升数据操作效率的利器
以耳倾听世间繁华,以语表达心中所想 大家好,我是whisperrrr. 前言: 大家好,我是你们的朋友whisrrr。在日常工作中,MySQL作为一款广泛使用的开源关系型数据库,其强大的功能为我们提供了便捷的数据存储和管理手段。而在…...
小米平板怎么和电脑共享屏幕
最近尝试使用小米平板和电脑屏幕分屏互联 发现是需要做特殊处理的,需要下载一款电脑安装包:小米妙享 关于这个安装包,想吐槽的是: 没有找到官网渠道,是通过其他网络方式查到下载的 不附录链接,原因是因为地…...
宝藏软件系列 篇一:My APK(Android)
文章目录 系列文章官方网站特色功能同类软件 系列文章 官方网站 My APK 官方版本是在 谷歌商店 中上架的。 官方下载地址:Google Play 商店页面。(需要外网) 2025.2最新版本的CSDN本地下载地址(因为是Android App Bundle&…...
本地 Ollama 部署 Deepseek R1 并使用 Spring AI Alibaba 构建 Chat 应用示例
本地部署 Deepseek R1 并使用 Spring AI Alibaba 构建 Chat 应用示例 Ollama 部署 Deepseek R1 官网:https://www.deepseek.com/ Github:https://github.com/deepseek-ai Ollama:https://ollama.com/ Docker Compose 部署一个 Ollama 和…...
centos8.0 docker ngnix
问题1:镜像拉取不下来,用DAO云加速器 问题2:ngnix镜像不能运行, 无法检索OCI运行时错误 在CentOS上使用Docker来运行Nginx是一个常见的做法,因为它提供了快速、一致的环境配置方式,并且可以很容易地扩展。…...
位运算在数据库中的运用实践-以MySQL和PG为例
目录 前言 一、两种不同的数据库设计 1、状态字段存储JSON 2、使用位运算 二、数据库中的位运算实践 1、MySQL中的位运算实践 2、PostgreSQL中位运算实践 三、总结 前言 最近在解决某用户的一个业务需求时,遇到一个很有意思的场景。首先先跟大家分享一下需…...
IoTDB 常见问题 QA 第五期
关于 IoTDB 的 Q & A 情人节之际,让 IoTDB Q&A 陪您一起共度解惑!我们将定期汇总我们将定期汇总社区讨论频繁的问题,并展开进行详细回答,通过积累常见问题“小百科”,方便大家使用 IoTDB。 Q1:导入…...
【kafka系列】日志存储设计 消息写入、读取
目录 日志存储设计 1. 日志存储的目录结构 2. 日志内容格式设计 3. 日志索引设计 4. 设计优势 消息写入流程 示例 流程图 消息读取流程 示例 关键设计细节 流程图 日志存储设计 Kafka的日志存储是其高吞吐、持久化能力的核心设计,其结构包含目录组织、…...
Python实现语音识别详细教程【2025】最新教程
文章目录 前言一、环境搭建1. 下载 Python2. 安装 Python3 使用 pip 安装必要的库 二、使用 SpeechRecognition 库进行语音识别1.识别本地音频文件2.实时语音识别3. 使用其他语音识别引擎 注意事项 前言 以下是一份较为完整的 Python 语音识别教程,涵盖环境搭建、使…...
【一文读懂】HTTP与Websocket协议
HTTP协议 概述 HTTP (Hypertext Transfer Protocol),即超文本传输协议,是一种用于在客户端和服务器之间传输超文本(例如网页、图片、音频、视频等)的通信协议。它是万维网(WWW)的基础,负责在浏…...
SpringBoot+微信小程序+数据可视化的宠物到家喂宠服务(程序+论文+讲解+安装+调试+售后等)
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统介绍 在经济高速发展、物质生活极大丰富的当下,人们的精神需求愈发凸显࿰…...
Windows逆向工程入门之堆栈结构与信息获取
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 1. 堆栈结构基础 堆栈的主要操作: 2. 代码功能解析 2.1 加载 ntdll.dll 2.2 获取 NtQueryInformationThread 函数指针 2.3 调用 NtQueryInformationThread 获取线程信息…...
springboot项目如何部署到tomcat中
1、使用springboot内部嵌入的tomcat 可以改一些tomcat的参数 2、可以把springboot项目打包为war包,然后部署到tomcat中去 Spring Boot 默认使用嵌入式 Tomcat 作为其 Web 容器,这使得 Spring Boot 应用可以作为一个独立的 JAR 文件运行。这种嵌入式服务…...
C语言之easyX
目录 概要 easyX整体架构 图形绘制 画布宽高 圆形 图片的贴图 加载图像 游戏框架 概要 easyX是一个轻量级的图形库,用于在Windows平台上进行简单的2D图形绘制。它提供了一组简单易用的函数,可以方便地绘制基本的图形元素,如线条、矩形、圆形…...
es6箭头函数和普通函数的区别
在JavaScript中,函数是执行特定任务的代码块。函数可以被定义并且随后被调用。JavaScript中有两种主要的函数定义方式:普通函数声明和箭头函数表达式。下面是这两种函数的定义方式及其区别和使用场景: 普通函数声明 普通函数可以通过函数声明…...
DeepSeek R1 32B 本地部署实战
#DeepSeek# DeepSeek是一款基于人工智能的智能助手,专为提升工作效率和信息获取能力而设计。它结合了自然语言处理、机器学习和大数据技术,能够快速理解用户需求并提供精准的答案或解决方案。 DeepSeek的核心功能 智能问答 DeepSeek可以回答各种问题&…...
八、SPI读写XT25数据
8.1 SPI 简介 SPI(Serial Peripheral Interface,串行外设接口)是一种同步串行通信协议,广泛用于嵌入式系统中连接微控制器与外围设备,如传感器、存储器、显示屏等。 主要特点 1. 全双工通信:支持同时发送…...
AIP-145 范围
编号145原文链接AIP-145: Ranges状态批准创建日期2020-05-28更新日期2020-05-28 服务通常需要表示具体值或连续值的范围。这些范围的含义存在诸多差异,也存在许多数据类型:整数、浮点数、时间戳等(在此仅举几例)。根据所讨论范围…...
(学习总结24)Linux 基本命令2
Linux 基本命令2 操作文件或目录命令更改文件或目录访问权限命令 chmod修改文件的所有者和所属组命令 chown修改文件或目录的所属组命令 chgrp更改文件或目录的属性命令 chattr创建文件和目录时的默认权限掩码命令 umask判断文件类型命令 file显示文件或文件系统状态命令 stat树…...
WPF-数据转换器
一、单值转换器 1.不传参数 转换器 当Value值大于100时返回红色 public class DataConverter : IValueConverter{/// <summary>/// 表示从源到目标数据转换/// </summary>/// <param name"value">数据源的值</param>/// <param name&q…...
STM32 I2C通信协议说明
目录 背景 I2C协议 数据的有效性 I2C通信开始和停止条件 I2C数据传输 发送 响应 正常情况: 异常情况: 主机结束接收 写寄存器的标准流程 读寄存器的标准流程 仲裁机制 时钟同步 SDA线的仲裁 程序 背景 对单片机的三大通信中的I2C通信进…...
网络工程师 (42)IP地址
一、定义与功能 IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。这种地址分配方式确保了用户在连网的计算机上操作时,能够高效且方便地从众多计算机中选出自己所需…...
Deepseek实用万能提问模板
一,背景需求约束条件 背景:提供与问题相关的时间、地点、人物、事件等信息,帮助 DeepSeek 更好地理解问题的情境。 需求:清晰明确地阐述你希望 DeepSeek完成的任务或提供的信息。 约束条件:可根据具体情况,对回答的范围、格式、字数等进行…...
强化学习笔记7——DDPG到TD3
前提:基于TD 的方法多少都会有高估问题,即Q值偏大。原因两个:一、TD目标是真实动作的高估。 二:自举法高估。 DDPG 属于AC方法:异策略,适合连续动作空间,因为他的策略网络直接输出的动作&#…...
传统混合专家模型MoE架构详解以及python示例(DeepSeek-V3之基础)
我们已经了解到DeepSeek-V3的框架结构基于三大核心技术构建:多头潜在注意力(MLA)、DeepSeekMoE架构和多token预测(MTP)。而DeepSeekMoE架构的底层模型采用了混合专家模型(Mixture of Experts,MoE)架构。所以我们先了解一下传统混合专家模型MoE架构。 一、传统混合专家模…...
开源协议深度解析:理解MIT、GPL、Apache等常见许可证
目录 前言1. MIT协议:自由而宽松的开源许可1.1 MIT协议的主要特点1.2 MIT协议的适用场景 2. GPL协议:自由软件的捍卫者2.1 GPL协议的核心理念2.2 GPL协议的适用场景 3. Apache License 2.0:开源与专利保护的平衡3.1 Apache License 2.0的主要…...