java基础(2) 面向对象编程-java核心类

面向对象

面向对象对应的就是面向过程,
面向过程就是一步一步去操作,你需要知道每一步的步骤。
面向对象的编程以对象为核心,通过定义类描述实体及其行为,并且支持继承、封装和多态等特性

面向对象基础

面向对象编程,是一种通过对象的方式,把现实世界映射到计算机模型的一种编程方法。
现实世界中,我们定义了“人”这种抽象概念,而具体的人则是“小明”、“小红”、“小军”等一个个具体的人。所以,“人”可以定义为一个类(class),而具体的人则是实例(instance):
在这里插入图片描述

class Test {private int field1;public String field2;// 构造函数public Test(String field2, int field1) {this.field1 = field1;this.field2 = field2;}public int getField1(){return this.field1;}public  void setField1(int val){if(val < 0 || val > 100){// 抛出错误throw new IllegalArgumentException("invalid age value");}// 赋值this.field1 = val;}
};public class Main {public static void main(String[] args){Test t = new Test();t.setField1(2);System.out.println(t.getField1());System.out.println(t.field2);}
}

写法同js类型,但是需要指定Test类型。一般字段使用private修饰符修饰,表示私有属性,外部无法访问,但是可以通过设置公共的方法去获取和设置值。
java类的构造函数,是public 类名(){},跟js的constructor(){}还是有点区别的。并且java可以写多个构造方法。除此之外,构造方法之间还能相互调用。

class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public Person(String name) {this(name, 18); // 调用另一个构造方法Person(String, int)}public Person() {this("Unnamed"); // 调用另一个构造方法Person(String)}
}
方法重载

如果有一系列方法,它们的功能都是类似的,只有参数有所不同,那么,可以把这一组方法名做成同名方法。
方法重载的目的是,功能类似的方法使用同一名字,更容易记住,因此,调用起来更简单。

 public  void setField1(int val){if(val < 0 || val > 100){// 抛出错误throw new IllegalArgumentException("invalid age value");}// 赋值this.field1 = val;}public  void setField1(int val, boolean isTrue){if(val < 0 || val > 100){// 抛出错误throw new IllegalArgumentException("invalid age value");}// 赋值this.field1 = val;}

比如String.indexOf()方法,就提供了多种调用方法。

举个例子,String类提供了多个重载方法indexOf(),可以查找子串:
int indexOf(int ch):根据字符的Unicode码查找;
int indexOf(String str):根据字符串查找;
int indexOf(int ch, int fromIndex):根据字符查找,但指定起始位置;
int indexOf(String str, int fromIndex)根据字符串查找,但指定起始位置。
继承

所有的类都默认继承与object,只有object例外,他没有父类。
java的继承同js差不多,只有一点区别,这里不多详述。

多态

子类可以重写父类的方法。这里需要注意,只有方法名,参数,返回值相同,才算是重写。加上@Overide装饰器可以方便编译器检查报错。

class Person {public void run() {System.out.println("Person.run");}
}
class Student extends Person {@Overridepublic void run() {System.out.println("Student.run");}
}

多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法;
没运行之前不知道运行的是父类的方法还是子类的方法。

如果父类不想子类继承某个方法,可以用final修饰方法。

class Person {protected String name;public final String hello() {return "Hello, " + name;}
}

用final修饰的类不允许被继承
用final修饰的属性,不允许被重新赋值

抽象类

如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法:

 abstract class Person {public abstract void run();
}

包含抽象方法的类不允许被实例化。抽象类强迫子类必须实现他的抽象方法。
用法跟ts类似,这里不多详述

面向抽象编程的本质就是:
  • 上层代码只定义规范(例如:abstract class Person);
  • 不需要子类就可以实现业务逻辑(正常编译);
  • 具体的业务逻辑由不同的子类实现,调用者并不关心。
接口

没有字段的,且全部方位都是抽象方法的抽象类,就可以改写为接口。

abstract class Person {public abstract void run();public abstract String getName();
}
//改写为
interface Person {void run();String getName();
}

接口定义的所有方法默认都是public abstract的
而当一个具体的类想去实现一个接口的时候,就需要使用implements,而非extends。
一个类只能继承于一个类,但是一个类可以implements多个接口。

在这里插入图片描述
接口之间也可以通过extends去继承。
接口还可以定义一个非抽象方法default,这个不强求类去实现,目的是为了:
当我们需要给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。

静态字段和静态方法

实例字段在每个实例中都有自己的一个独立“空间”,但是静态字段只有一个共享“空间”,所有实例都会共享该字段。举个例子:

class Person {public String name;public int age;// 定义静态字段number:public static int number;
}

对于静态字段,无论修改哪个实例的静态字段,效果都是一样的:所有实例的静态字段都被修改了,原因是静态字段并不属于实例;
在这里插入图片描述
可以把静态字段立即为类自己的属性,一般通过类.字段去获取,而不是通过实例.字段去获取。

同理,静态方法也一致,属于类,可以直接通过类.方法名去调用,但是内部无法访问this。
静态方法经常用于工具类。例如:
Arrays.sort()
Math.random()

在Java中,我们使用package来解决名字冲突。
Java定义了一种名字空间,称之为包:package。一个类总是属于某个包,类名(比如Person)只是一个简写,真正的完整类名是包名.类名。
类似于ts的namespace,防止命名冲突。
JDK的Arrays类存放在包java.util下面,因此,完整类名是java.util.Arrays。
包的命名跟文件存放位置也有关。
在这里插入图片描述

导入其他包

  • 直接写完整的包名: lin.TestClass
  • 先在当前包import lin.TestClass ,就可以直接用了new TestClass
  • 也可以直接import lin.*,他会将lin包的class引入。
  • 默认引入java.lang的包,比如String, 这些。
作用域

比如public、protected、private,这些修饰符,用来限定作用域的范围。
publci的类,可以被其他包访问。public的属性和方法,也可以被其他类访问。
非publci的类,外部无法访问,就跟js没有export一样
private定义的方法和属性,无法在类外被访问。
由于Java支持嵌套类,如果一个类内部还定义了嵌套类,那么,嵌套类拥有访问private的权限:

public class Main {public static void main(String[] args) {Inner i = new Inner();i.hi();}// private方法:private static void hello() {System.out.println("private hello!");}// 静态内部类:static class Inner {public void hi() {Main.hello();}}
}

private定义的字段和方法,其继承类中无法使用,procted修饰的方法和字段,可以在子类中使用,但同样不可以被实例调用。

package权限(包作用域)
最后,包作用域是指一个类允许访问同一个package的没有private修饰的class,以及没有protected、private修饰的字段和方法。
final

  • 用final修饰class可以阻止被继承:
  • 用final修饰method可以阻止被子类覆写
  • 用final修饰字段可以阻止被重新赋值
  • 用final修饰局部变量可以阻止被重新赋值
内部类

在这里插入图片描述

也是嵌套类。

classpath和jar

classpath是JVM用到的一个环境变量,它用来指示JVM如何搜索class
现在我们假设classpath是.;C:\work\project1\bin;C:\shared,当JVM在加载abc.xyz.Hello这个类时,会依次查找:

  • <当前目录>\abc\xyz\Hello.class
  • C:\work\project1\bin\abc\xyz\Hello.class
  • C:\shared\abc\xyz\Hello.class

在系统环境变量中设置classpath环境变量,不推荐;
在启动JVM时设置classpath变量,推荐。
启动jvm的时候🌽定义
java -classpath .;C:\work\project1\bin;C:\shared abc.xyz.Hello

jar包

如果有很多.class文件,散落在各层目录中,肯定不便于管理。如果能把目录打一个包,变成一个文件,就方便多了。

jar包就是用来干这个事的,它可以把package组织的目录层级,以及各个目录下的所有文件(包括.class文件和其他文件)都打成一个jar文件,这样一来,无论是备份,还是发给客户,就简单多了。

jar包相当于目录,可以包含很多.class文件,方便下载和使用;

MANIFEST.MF文件可以提供jar包的信息,如Main-Class,这样可以直接运行jar包。

java核心类

字符串

实际上字符串在String内部是通过一个char[]数组表示的,因此,按下面的写法也是可以的:

String s2 = new String(new char[] {'H', 'e', 'l', 'l', 'o', '!'});

Java字符串的一个重要特点就是字符串不可变。这种不可变性是通过内部的private final char[]字段,以及没有任何修改char[]的方法实现的。
不可变不是说变量s2不可变,s2可以重新赋值一个新的String对象,只不过原有的String对象不会改变。

字符串比较

java拥有一个字符串常量池,如果多个字符串具有相同的值,那么他们将共享存储在常量池中的同一个实例,也就是说
String s = "hello",这个hello,实际上是存放在常量池中,s存放的值是hello的地址,类似于js的对象,只不过js的字符串是基础类型而不是引用类型。
当我们想要比较两个字符串是否相同时,要特别注意,我们实际上是想比较字符串的内容是否相同。必须使用equals()方法而不能用==
因为==实际上比较的是内存地址,

 		String s1 = "hello";String s2 = "HELLO".toLowerCase();System.out.println(s1 == s2);System.out.println(s1.equals(s2));

==返回false,只有equals才返回true。

其他字符串方法同js类似

"Hello".indexOf("l"); // 2
"Hello".lastIndexOf("l"); // 3
"Hello".startsWith("He"); // true
"Hello".endsWith("lo"); // true
"Hello".substring(2); // "llo"
"Hello".substring(2, 4); "ll"
"  \tHello\r\n ".trim(); // "Hello" 返回的Hello是新的String对象"".isEmpty(); // true,因为字符串长度为0
"  ".isEmpty(); // false,因为字符串长度不为0
"  \n".isBlank(); // true,因为只包含空白字符
" Hello ".isBlank(); // false,因为包含非空白字符String[] arr = {"A", "B", "C"};
String s = String.join("***", arr); // "A***B***C"//字符串占位 
String s = "Hi %s, your score is %d!";
System.out.println(s.formatted("Alice", 80));
System.out.println(String.format("Hi %s, your score is %.2f!", "Bob", 59.5));
字符串转换

要把任意基本类型或引用类型转换为字符串,可以使用静态方法valueOf()。这是一个重载方法,编译器会根据参数自动选择合适的方法。

String.valueOf(123); // "123"
String.valueOf(45.67); // "45.67"
String.valueOf(true); // "true"
String.valueOf(new Object()); // 类似java.lang.Object@636be97c//int
int n1 = Integer.parseInt("123"); // 123
int n2 = Integer.parseInt("ff", 16); // 按十六进制转换,255// boolean
boolean b1 = Boolean.parseBoolean("true"); // true
boolean b2 = Boolean.parseBoolean("FALSE"); // false// char 和 String 互转
char[] cs = "Hello".toCharArray(); // String -> char[]
String s = new String(cs); // char[] -> Stringbyte[] b1 = "Hello".getBytes(); // 按系统默认编码转换,不推荐
byte[] b2 = "Hello".getBytes("UTF-8"); // 按UTF-8编码转换
byte[] b2 = "Hello".getBytes("GBK"); // 按GBK编码转换
byte[] b3 = "Hello".getBytes(StandardCharsets.UTF_8); // 按UTF-8编码转换byte[] b = ...
String s1 = new String(b, "GBK"); // 按GBK转换
String s2 = new String(b, StandardCharsets.UTF_8); // 按UTF-8转换
小结
  • Java字符串String是不可变对象;
  • 字符串操作不改变原字符串内容,而是返回新字符串;
  • 常用的字符串操作:提取子串、查找、替换、大小写转换等;
  • Java使用Unicode编码表示String和char;
  • 转换编码就是将String和byte[]转换,需要指定编码;
  • 转换为byte[]时,始终优先考虑UTF-8编码。
StringBuilder

Java编译器对String做了特殊处理,使得我们可以直接用+拼接字符串
但是

String s = "";
for (int i = 0; i < 1000; i++) {s = s + "," + i;
}

上面循环代码,每次循环都会创建新的String对象,而老的String对象则被丢弃,造成内存浪费,所以java提供StringBuilder来高校拼接String;
Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象:

StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {sb.append(',').append(i);
}
String s = sb.toString();

注意:对于普通的字符串+操作,并不需要我们将其改写为StringBuilder,因为Java编译器在编译时就自动把多个连续的+操作编码为StringConcatFactory的操作。在运行期,StringConcatFactory会自动把字符串连接操作优化为数组复制或者StringBuilder操作。

小结

  • StringBuilder是可变对象,用来高效拼接字符串;
  • StringBuilder可以支持链式操作,实现链式操作的关键是返回实例本身;
StringJoiner

类似用分隔符拼接数组的需求很常见,所以Java标准库还提供了一个StringJoiner来干这个事:

public class Main {public static void main(String[] args) {String[] names = {"Bob", "Alice", "Grace"};var sj = new StringJoiner(", ", "Hello ", "!");for (String name : names) {sj.add(name);}System.out.println(sj.toString());}
}

第一个参数指定拼接的字符串,第二个参数指定开头,第三个参数指定结尾。
String还提供了一个静态方法join(),这个方法在内部使用了StringJoiner来拼接字符串,在不需要指定“开头”和“结尾”的时候

String[] names = {"Bob", "Alice", "Grace"};
var s = String.join(", ", names);
包装类型

在这里插入图片描述
Integer类实现,

public class Integer {private int value;public Integer(int value) {this.value = value;}public int intValue() {return this.value;}
}

在这里插入图片描述

有点像js中,string对应的String, number对应的Numer,
int 和Integer可以互相转换

int i = 100;
Integer n = Integer.valueOf(i);
int x = n.intValue();Integer n = 100; // 编译器自动使用Integer.valueOf(int)
int x = n; // 编译器自动使用Integer.intValue()

所有的包装类都是不变类,

public final class Integer {private final int value;
}

init在初始化赋值之后,将不能再修改;
对两个Integer实例进行比较要特别注意:绝对不能用==比较,因为Integer是引用类型,必须使用equals()比较

public class Main {public static void main(String[] args) {Integer x = 127;Integer y = 127;Integer m = 99999;Integer n = 99999;System.out.println("x == y: " + (x==y)); // trueSystem.out.println("m == n: " + (m==n)); // falseSystem.out.println("x.equals(y): " + x.equals(y)); // trueSystem.out.println("m.equals(n): " + m.equals(n)); // true}
}

值较小的Integer比较是相等的,这是因为,在Integer内部,为了优化性能,对于较小的,Integer.initValue总是返回同一个实例,这也导致==为true。

Integer x = 127
//等同于
Integer x = Integer.valueOf(127)

Integer.valueOf()就是静态工厂方法,它尽可能地返回缓存的实例以节省内存。
创建新对象时,优先选用静态工厂方法而不是new操作符。

进制转换

Integer本身还提供了很多方法,就跟js的Number.xxx一样,

  • parseInt 将其他类型转为Integer类型
int x1 = Integer.parseInt("100"); // 100
int x2 = Integer.parseInt("100", 16); // 256,因为按16进制解析System.out.println(Integer.toString(100)); // "100",表示为10进制
System.out.println(Integer.toString(100, 36)); // "2s",表示为36进制
System.out.println(Integer.toHexString(100)); // "64",表示为16进制
System.out.println(Integer.toOctalString(100)); // "144",表示为8进制
System.out.println(Integer.toBinaryString(100)); // "1100100",表示为2进制

Java的包装类型还定义了一些有用的静态变量

// boolean只有两个值true/false,其包装类型只需要引用Boolean提供的静态字段:
Boolean t = Boolean.TRUE;
Boolean f = Boolean.FALSE;
// int可表示的最大/最小值:
int max = Integer.MAX_VALUE; // 2147483647 类似于js的x`
int min = Integer.MIN_VALUE; // -2147483648
// long类型占用的bit和byte数量:
int sizeOfLong = Long.SIZE; // 64 (bits)
int bytesOfLong = Long.BYTES; // 8 (bytes)

所有的整数和浮点数的包装类型都继承Number,因此,可以非常方便地直接通过包装类型获取各种基本类型:

// 向上转型为Number:
Number num = new Integer(999);
// 获取byte, int, long, float, double:
byte b = num.byteValue();
int n = num.intValue();
long ln = num.longValue();
float f = num.floatValue();
double d = num.doubleValue();
JavaBean

符合以下这种

// 读方法:
public Type getXyz()
// 写方法:
public void setXyz(Type value)

读写方法名分别以get和set开头,并且后接大写字母开头的字段名Xyz,因此两个读写方法名分别是getXyz()和setXyz()。
类似于js的defineProperty的get set方法。

JavaBean是一种符合命名规范的class,它通过getter和setter来定义属性;
属性是一种通用的叫法,并非Java语法规定;
可以利用IDE快速生成getter和setter;
使用Introspector.getBeanInfo()可以获取属性列表。

枚举类

在Java中,我们可以通过static final来定义常量

public class Weekday {public static final int SUN = 0;public static final int MON = 1;public static final int TUE = 2;public static final int WED = 3;public static final int THU = 4;public static final int FRI = 5;public static final int SAT = 6;
}

enum
为了让编译器能自动检查某个值在枚举的集合内,并且,不同用途的枚举需要不同的类型来标记,不能混用,我们可以使用enum来定义枚举类:

public class Main {public static void main(String[] args) {Weekday day = Weekday.SUN;if (day == Weekday.SAT || day == Weekday.SUN) {System.out.println("Work at home!");} else {System.out.println("Work at office!");}}
}enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT;
}

有点类型于ts的enum,

  • 不同类型的枚举,不能相互赋值。
  • 不同类型的值,不可以直接==
 Test1 tt = Test1.TEST_1;
tt = HAHA.HAHA_1;
int test = 1;
test == Test1.TEST_1;enum Test1 { TEST_1, TEST_2 };
enum HAHA {HAHA_1, HAHA_2};

enum实际上创建的也是一个class

  • 定义的enum类型总是继承自java.lang.Enum,且无法被继承;
  • 只能定义出enum的实例,而无法通过new操作符创建enum的实例;
  • 定义的每个实例都是引用类型的唯一实例;
  • 可以将enum类型用于switch语句。
public enum Color {RED, GREEN, BLUE;
}
//实际上public final class Color extends Enum { // 继承自Enum,标记为final class// 每个实例均为全局唯一:public static final Color RED = new Color();public static final Color GREEN = new Color();public static final Color BLUE = new Color();// private构造方法,确保外部无法调用new操作符:private Color() {}
}

每个实例都是全局唯一
编译后的enum类和普通class并没有任何区别。但是我们自己无法按定义普通class那样来定义enum,必须使用enum关键字,这是Java语法规定的。

因为enum是一个class,每个枚举的值都是class实例,因此,这些实例有一些方法:name()

String s = Weekday.SUN.name(); // "SUN"
int n = Weekday.MON.ordinal(); // 1 返回定义的常量的顺序,从0开始计数

因为enum实际上定义的也是类,所以可以根据构造函数,添加每个实例对应的属性。比如

enum Weekday {MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0);public final int dayValue;private Weekday(int dayValue) {this.dayValue = dayValue;}
}public static void main(String[] args) {Weekday day = Weekday.SUN;if (day.dayValue == 6 || day.dayValue == 0) {System.out.println("Work at home!");} else {System.out.println("Work at office!");}}

MON(1)相当于执行new操作,将1传入作为dataValue的值,这样就可以通过.dataValue去获取值。
再比如

enum Weekday {MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");public final int dayValue;private final String chinese;private Weekday(int dayValue, String chinese) {this.dayValue = dayValue;this.chinese = chinese;}@Overridepublic String toString() {return this.chinese;}
}

还可以多用其他属性,然后重新toString方法。name属于final,无法被重写。
小结

  • Java使用enum定义枚举类型,它被编译器编译为final class Xxx extends Enum { … };
  • 通过name()获取常量定义的字符串,注意不要使用toString();
  • 通过ordinal()返回常量定义的顺序(无实质意义);
  • 可以为enum编写构造方法、字段和方法
  • enum的构造方法要声明为private,字段强烈建议声明为final;
  • enum适合用在switch语句中。
BigInteger BigDecimal

整数最大是long类型,超过了的话,java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:

BigInteger bi = new BigInteger("1234567890");
System.out.println(bi.pow(5)); // 2867971860299718107233761438093672048294900000

和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。
实际上一个BigDecimal是通过一个BigInteger和一个scale来表示的,即BigInteger表示一个完整的整数,而scale表示小数位数

public class BigDecimal extends Number implements Comparable<BigDecimal> {private final BigInteger intVal;private final int scale;
}
常用工具类

Math
顾名思义,Math类就是用来进行数学计算的,它提供了大量的静态方法来便于我们实现数学计算:

Math.abs(-13) //13 绝对值
Math.max(13,9) //13 最大
Math.min() //最小
Math.pow(2, 10); // 2的10次方=1024
double pi = Math.PI; // 3.14159...
double e = Math.E; // 2.7182818...
Math.sin(Math.PI / 6); // sin(π/6) = 0.5
Math.random(); // 0.53907... 每次都不一样

Java标准库还提供了一个StrictMath,它提供了和Math几乎一模一样的方法。这两个类的区别在于,由于浮点数计算存在误差,不同的平台(例如x86和ARM)计算的结果可能不一致(指误差不同),因此,StrictMath保证所有平台计算结果都是完全相同的,而Math会尽量针对平台优化计算速度,所以,绝大多数情况下,使用Math就足够了。
·
Random
生成伪随机数

Random r = new Random();
r.nextInt(); // 2071575453,每次都不一样
r.nextInt(10); // 5,生成一个[0,10)之间的int
r.nextLong(); // 8811649292570369305,每次都不一样
r.nextFloat(); // 0.54335...生成一个[0,1)之间的float
r.nextDouble(); // 0.3716...生成一个[0,1)之间的double

SecureRandom
有伪随机数,就有真随机数。实际上真正的真随机数只能通过量子力学原理来获取,而我们想要的是一个不可预测的安全的随机数,SecureRandom就是用来创建安全的随机数的:

SecureRandom sr = new SecureRandom();
System.out.println(sr.nextInt(100));

SecureRandom的安全性是通过操作系统提供的安全的随机种子来生成随机数。这个种子是通过CPU的热噪声、读写磁盘的字节、网络流量等各种随机事件产生的“熵”。

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

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

相关文章

HARRYPOTTER: FAWKES

攻击机 192.168.223.128 目标机192.168.223.143 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.143 开启了21 22 80 2222 9898 五个端口&#xff0c;其中21端口可以匿名FTP登录&#xff0c;好像有点说法,百度搜索一下发现可以用anonymous登录…

L1-088 静静的推荐

一、题目 二、解题思路 如果有的学生天梯赛成绩虽然与前一个人相同&#xff0c;但其参加过 PAT 考试&#xff0c;且成绩达到了该企业的面试分数线&#xff0c;则也可以接受——同一批次这样的人可以有多个&#xff01;&#xff01;&#xff01;如果 pta 分数不低于 175 &#…

手把手教你开发Python桌面应用-PyQt6图书管理系统-图书添加模块UI设计实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…

如何写一个其他人可以使用的GitHub Action

前言 在GitHub中&#xff0c;你肯定会使用GitHub Actions自动部署一个项目到GitHub Page上&#xff0c;在这个过程中总要使用workflows工作流&#xff0c;并在其中使用action&#xff0c;在这个使用的过程中&#xff0c;总会好奇怎么去写一个action呢&#xff0c;所以&#xff…

Linux线程 分离和同步与互斥 条件变量

Linux线程 分离和同步与互斥 条件变量 1. 分离线程2. 线程互斥与互斥量3. 线程同步与竞态条件4. pthread库与条件变量5. 生产者-消费者 1. 分离线程 什么是线程分离&#xff1f; 线程分离是指线程在结束时&#xff0c;操作系统会自动回收其资源&#xff0c;而无需其他线程显式地…

Java:内部类、枚举、泛型以及常用API --黑马笔记

内部类 内部类是类中的五大成分之一&#xff08;成员变量、方法、构造器、内部类、代码块&#xff09;&#xff0c;如果一个类定义在另一个类的内部&#xff0c;这个类就是内部类。 当一个类的内部&#xff0c;包含一个完整的事物&#xff0c;且这个事物没有必要单独设计时&a…

[职场] 进入大数据领域需要掌握哪些软件 #其他#职场发展#职场发展

进入大数据领域需要掌握哪些软件 学习大数据首先我们要学习Java语言和Linux操作系统&#xff0c;这两个是学习大数据的基础&#xff0c;学习的顺序不分前后。 Java 大家都知道Java的方向有JavaSE、JavaEE、JavaME&#xff0c;学习大数据要学习那个方向呢? 只需要学习Java的…

2024 年 6 款值得推荐的 iOS 系统恢复软件

iPhone 以其时尚的设计、用户友好的界面和强大的性能而闻名。然而&#xff0c;没有任何技术能够避免错误和故障&#xff0c;iPhone 也不例外。作为 iPhone 用户&#xff0c;您可能遇到过各种可能导致设备故障的问题。虽然 Apple 提供了多种解决方案来解决这些问题&#xff0c;但…

算法练习-二叉搜索树中的搜索(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;二叉树 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨…

Linux系统安装(CentOS Vmware)

学习环境安装 VMware安装 VMware下载&安装 访问官网&#xff1a;https://www.vmware.com 在此处可以选择语言 点击China&#xff08;简体中文&#xff09; 点击产品&#xff0c;点击Workstation Pro 下滑&#xff0c;点击下载试用版 下滑找到Workstation 17 Pro for Wi…

Linux开发:PAM1 介绍

PAM(Pluggable Authentication Modules )是Linux提供的一种通用的认证方式,他可以根据需要动态的加载认证模块,从而减少认证开发的工作量以及提供认证的灵活度。 1.PAM的框架 PAM的框架由一下几个部分构成 1)应用程序,即需要使用认证服务的程序,这些应用程序是使用抽象…

【大厂AI课学习笔记】1.5 AI技术领域(6)目标检测

目标检测是CV中的重要场景。 在图像中定位感兴趣的目标&#xff0c;准确判断每个目标的类别&#xff0c;并给出每个目标的边界框。 上图是目标检测的典型应用案例。 目标检测的难点是小目标的高精度检测。 目前主要的应用领域是机器人导航、自动驾驶、智能视频监督、工业检测…

fast table行的自动扩大

首先选择行 选择表格或其任何元素&#xff0c;并将光标置于所需行的左侧。光标的形式将变为一个黑色小箭头&#xff1a; 单击鼠标左键&#xff0c;以选择行&#xff1b; 右击鼠标&#xff0c;显示该行的右键菜单 最好的行分断 第 [ToInt32([Page])-4] 页

K8S之标签的介绍和使用

标签 标签定义标签实操1、对Node节点打标签2、对Pod资源打标签查看资源标签删除资源标签 标签定义 标签就是一对 key/value &#xff0c;被关联到对象上。 标签的使用让我们能够表示出对象的特点&#xff0c;比如使用在Pod上&#xff0c;能一眼看出这个Pod是干什么的。也可以用…

基于SpringBoot和PostGIS的震中影响范围可视化实践

目录 前言 一、基础数据 1、地震基础信息 2、全国行政村 二、Java后台服务设计 1、实体类设计 2、Mapper类设计 3、控制器设计 三、前端展示 1、初始化图例 2、震中位置及影响范围标记 3、行政村点查询及标记 总结 前言 地震等自然灾害目前还是依然不能进行准确的预…

小明与光明之剑:勇者的试炼

现在&#xff0c;我将根据这些步骤编写一个对话形式的童话故事。 很久很久以前&#xff0c;在一个遥远的国度里&#xff0c;有一个勇敢的小男孩叫小明。有一天&#xff0c;他得知自己的村庄正遭受一只凶猛的巨龙侵袭&#xff0c;许多村民都受到了伤害。 小明决定踏上征程&#…

Java面向对象 多态

目录 多态多态的好处实例创建一个Main 多态 在Java中&#xff0c;多态是面向对象编程的三大基本特性之一&#xff0c;另外两个是封装和继承。多态是指一个接口可以有多种实现方式&#xff0c;或者一个对象可以表现出多种形态。 在Java中&#xff0c;多态主要通过方法重载和重写…

新增同步管理、操作日志模块,支持公共链接分享,DataEase开源数据可视化分析平台v2.3.0发布

2024年2月5日&#xff0c;DataEase开源数据可视化分析平台正式发布v2.3.0版本。 这一版本的功能升级包括&#xff1a;新增“同步管理”功能模块&#xff0c;用户可通过此模块&#xff0c;将传统数据库中的数据定时同步到Apache Doris中&#xff0c;让数据分析更快速&#xff1…

寒假思维训练day19

更新一道div3的F 和 做出来过的一道类似这个F的 icpc铜牌题, 美赛以后的第一篇。 题目链接&#xff0c;有需自取&#xff1a; div3 F链接&#xff1a;Problem - F - Codeforces icpc Asia macau 铜牌题 Problem - K - Codeforces 摘要 Part1 div3 F 的题意、题解、代码…

SolidWorks学习笔记——草图绘制的基本命令

目录 一、进入草图绘制 二、直线命令与删除命令 三、圆弧命令与矩形命令 四、槽口命令以及多边形命令 五、椭圆以及倒角命令 六、草图绘制中的剪裁命令 七、草图中的几何关系 八、草图绘制中的智能尺寸 九、从外部粘贴草图&#xff08;CAD&#xff09; 一、进入草图绘…