当前位置: 首页 > news >正文

Java基础总结上(Ref:JavaGuide)

基础概念与常识

Java语言有哪些特点,优点?

简单易学,是一门面向对象的语言,有封装继承多态三大特性,而且有多重防护机制保证安全性,例如权限修饰符,限制程序直接访问操作系统资源。通过JIT编译器提升了Java语言的运行效率,还有一点就是平台的无关性,Java语言并不依赖系统平台,而是依赖虚拟机,“Write once , Run anywhere"一次编写,随处运行,是Java最大的优势之一,还有就是Java强大的生态。

JavaSE和JavaEE

JavaSE:

是Java平台的标准版,java语言的基础,适合简单的开发。

JavaEE:

Java平台的企业版,也可以说是高级版本,包含了支持企业级开发部署的标准和规范,例如:Servlet,JSP,JDBC等,建立在javaee的基础上,适合开发复杂的企业级应用。

JVM vs JDK vs JRE

JVM:

是运行Java字节码的虚拟机,jvm对于不同的系统有不同的实现,目的就是为了使用相同的字节码给出相同的结果,字节码和不同系统的JVM是java语言一次编译,随处运行的关键所在。

JVM并不是只有一种,只要满足Jvm规范,都可以开发属于自己的JVM。

JVM种类;最常用:HotSpot VM,J9 VM,Zing VM等。

JDK和JRE

jdk是一个功能齐全的Java开发工具包,用于创建和编译Java程序,它包含了JRE,以及编译器javac和其它工具。

JRE是运行已编译的java程序所需要的环境,主要包含两个部分:jvm和Java基础类库,java基础类库就是提供了常用的功能和API,如IO操作,网络通信,数据结构等。

简单来说,JRE只包含了运行Java程序所需要的环境和类库,而JDK不仅包含了JRE,还包括了Java开发和调试的工具。

不过从JDK9开始,就不区分二者的关系了,取而代之的是模块系统(JDK 被重新组织成 94 个模块)+ jlink 工具 (随 Java 9 一起发布的新命令行工具。

什么是字节码?采用字节码的好处?

在java中,可以被jvm识别的代码就是字节码,扩展名为.class的文件。字节码并不针对于特定的机器,所以java程序无需重新编译便可以在多种不同操作系统的计算机上运行,其实就是字节码面向JVM,而非操作系统。

.class字节码文件经类加载器加载到JVM中,然后解释器开始逐行解释执行,但是如果让解释器老执行一些热点代码,那么效率就太低了,所以引进了JIT编译器即时编译,JIT会判断哪些是热点代码,然后将他们编译成机器码并保存下来,机器码就是二进制文件,直接由CPU执行,所以机器码的运行效率肯定高于解释器,那么那些热点代码就不用解释器重复解释了,效率也就高了,这也就是为什么说Java是编译与解释共存的语言。

如何判断哪些是热点代码呢?

JVM会设置一个阈值,当方法或者代码块在一定时间内的调用次数超过这个阈值时就会被JIT编译,存入codeCache中,当下次执行时,在遇到这段代码,就会从codeCache中读取机器码,直接执行,以此来提升程序运行的性能。

详情可以:[基本功 | Java即时编译器原理解析及实践]

为什么说Java语言编译与解释并存?

高级编程语言按照程序的执行方式分为两种:

编译型语言:

编译型语言通过编译器将源代码一次性翻译成可以被该平台执行的机器码。一般情况下开发效率较低,但是执行速度较快。常见的编译型语言有:c,cpp,go,rust。

解释型语言:

解释型语言通过解释器一句一句的将代码解释为机器代码后在执行。开发效率较快,执行速度较慢,例如python,js,php。

而Java具有这二者的特征,因为Java编写的程序要先被编译为字节码文件,然后这种字节码文件必须由Java解释器来执行,这就是为什么java编译与解释共存。

AOT有什么优点?为什么不全部使用AOT?

从图中我们可以看到到一个Java程序从启动到被JIT动态编译优化会经过好几个过程(VM init,App init 和 App active 几个阶段),冷启动问题比较严重,而且在这几个过程中,运行内存占用较高,因为JVM会并不知道哪些是热点代码,所以会将所有代码全部加载,这就造成了实际加载的代码比实际需要运行的代码多很多的情况,这就是因为Java程序的编译优化在程序运行时,但是如果可以将编译优化这一步骤提前到运行前,就可以避免加载不必要的代码,这就是AOT(提前编译、静态编译)。

AOT的核心思想就是:将Java程序的编译阶段提前到程序启动前,然后在编译阶段进行代码编译优化,也就是说在程序被执行前就将其编译成机器码,让程序启动即巅峰,消除冷启动,降低运行时内存消耗,而且AOT编译后的代码不容易被反编码和修改,特别适合云原生的场景。

但是并不是所有场景都可以使用AOT,因为AOT无法支持Java的一些动态特性,如反射,动态代理,动态加载等,然而很多的框架都用到了这些特性,例如Spring,CGLIB。举个例子,CGLIB动态代理使用的是ASM技术,而这种技术大致原理是运行时直接在内存中生成并加载修改后的字节码文件,如果全部使用AOT提前编译,也就不能使用ASM技术,为了支持类似的动态特性,所以选择使用JIT即时编译。

Java和C++的区别

Java不提供指针来直接访问内存,程序内存更加安全。

Java的类是单继承的,C++支持多继承,虽然Java的类不可以多继承,但是接口可以多继承。

Java有自动内存管理垃圾回收机制(GC),不需要程序员去手动释放无用内存。

C++增加了操作符的重载,而Java只支持方法的重载。

基本语法

注释有哪几种形式?

单行注释:通常用于解释方法内某单行代码的作用。

多行注释: 通常用于解释一段代码的作用。

文档注释:通常用于生成Java开发文档。(使用相对较少)

注释是我们的代码说明书,能够帮助看代码的热能快速的理清代码之间的逻辑关系。因此,在写程序的时候随后加上注释是一个非常好的习惯。但是注释不是越详细越好,因为好的代码本身就是注释,我们要尽量规范和美化自己的代码来减少不要的注释。如果编程语言足够有表达能力,就不需要注释,尽量通过代码来阐述。

标识符和关键字的区别?

标识符就是一个名字,比如类,变量,方法的名字,这些就是标识符,但是有一些标识符,Java语言已经赋予了他们特殊的意义,而且只能用在特定的地方,这些特殊的标识符就是关键字,简单来说,关键字就是有特殊含义的标识符

Java中的关键字有哪些?

访问控制:private,protected,public

类,方法,变量修饰符:abstract,class,extend,final,implement,new等

程序控制类:break,continue,return,do,while,for,switch,case等

错误处理:try,catch,throw,finally等

包相关:import,package

基本类型:boolean,byte,char,double,float,short。

变量引用:super,this,void。

保留字:goto,const。

自增自减运算符

++--是Java提供的自增自减运算符,既可以放在变量之前,也可以放在变量之后。

前缀形式:++a或--a先自增/自减变量的值,然后再使用该变量,例如:b=++a先将a增加1,然后把增加后的值赋值b

后缀形式:a++或a--先使用变量的当前值,然后再自增或自减变量的值,例如,b=a++先将a的值赋值给b,然后再将a增加1

口诀:符号在前就先加减,符号在后就后加减

移位运算符

移位操作中,被操作的数据被视为二进制数,移位就是将其向左或向右移动若干位的运算。

Java中有三种移位运算符:

  1. 左移运算符(<<)

    • 作用:将操作数的所有位向左移动指定的位数。

    • 格式:value << num

    • 示例:int a = 8; // 二进制表示为 1000 int b = a << 2; // 结果为 32,二进制表示为 100000

  2. 右移运算符(>>)

    • 作用:将操作数的所有位向右移动指定的位数。对于正数,左侧空出的位用0填充;对于负数,左侧空出的位用1填充(保持符号位不变)。

    • 格式:value >> num

    • 示例:int a = 8; // 二进制表示为 1000 int b = a >> 2; // 结果为 2,二进制表示为 10

  3. 无符号右移运算符(>>>)

    • 作用:将操作数的所有位向右移动指定的位数。左侧空出的位总是用0填充,不考虑符号位。

    • 格式:value >>> num

    • 示例:int a = -8; // 二进制表示为 11111111111111111111111111111000 int b = a >>> 2; // 结果为 1073741822,二进制表示为 00111111111111111111111111111110

使用移位运算符的主要原因:

高效:移位运算符直接对应于处理器的移位指令。

节省内存:通过移位操作,可以使用一个整数(如int或long)来存储多个布尔值或标志位,从而节省内存。

需要注意的是移位运算符不会改变原来的数值,而是返回一个新的值

continue,break和return的区别?

当我们在循环之中,达到某种条件需要提前结束循环时,就需要用到以下三个:

continue:跳出当前这一次循环,继续执行下一次循环。

break:跳出整个循环体,继续执行下面的语句。

return一般有两种用法:

1.直接使用return结束方法执行,用于没有返回值函数的方法

2.return一个特定值,即方法的返回值,用于有返回值函数的方法

Java中的基本数据类型

Java'中有八种基本数据类型:

6种数字类型:整数型:byte,int,short,long 浮点型:float,double

1种字符类型:char

1种布尔型:boolean

可以从图中看到byteshortintlong能表示的最大正数都减 1 了,因为在二进制补码的表示法中,最高位是用来表示符号的(0表示正数,1表示负数),其余位表示数值部分,所以如果我们要表示最大的正数,那么只需要把除了最高魏之外的所有位都设为1,如果再加上1,就会导致溢出,变成一个负数。

注意:

  1. Java 里使用 long 类型的数据一定要在数值后面加上 L,否则将作为整型解析。

  2. Java 里使用 float 类型的数据一定要在数值后面加上 f 或 F,否则将无法通过编译。

  3. char a = 'h'char :单引号,String a = "hello" :双引号。

这八种基本类型都有对应的包装类分别为:ByteShortIntegerLongFloatDoubleCharacterBoolean

基本数据类型和包装类型的区别?

用途:在定义常量和局部变量时,会使用基本数据类型,在其他地方比如方法参数,对象属性中很少会使用基本类型来定义变量。并且,包装类型可用于泛型,而基本类型不可以。

存储方式:基本数据类型的局部变量存放在Java虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被static修饰)存放在Java虚拟机的堆中。包装类型属于对象类型,几乎所有的对象实例都存在于堆中。

占用空间:相比于包装类型(对象类型),基本数据类型占用的空间往往非常小。

默认值:成员变量包装类型不赋值就是null,而基本类型有默认值且不是null。

比较方式:对于基本数据类型来说,==比较的是值。对于包装数据类型来说,==比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用equals()方法。

并不是所有的基本数据类都存放在栈中:基本数据类型的存储位置取决他们的作用域和声明方式。如果是局部变量,会存放在栈中,如果是成员变量,会存储在堆/方法区/元空间中

public class Test {// 成员变量,存放在堆中int a = 10;// 被 static 修饰的成员变量,JDK 1.7 及之前位于方法区,1.8 后存放于元空间,均不存放于堆中。// 变量属于类,不属于对象。static int b = 20;
​public void method() {// 局部变量,存放在栈中int c = 30;static int d = 40; // 编译错误,不能在方法中使用 static 修饰局部变量}
}

包装类型的缓存机制

Java基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。

Byte,Short,Integer,Long这四种包装类默认创建了数值[-128,127]的相应类型的缓存数据,Character创建了数值在[0,127]范围的缓存数据,Boolean直接返回True和False。浮点数的包装类型并没有实现缓存机制。

public class IntegerCacheExample {public static void main(String[] args) {Integer a = 100;Integer b = 100;
​Integer c = 200;Integer d = 200;
​// 输出true,因为a和b引用的是缓存中的同一个对象System.out.println(a == b);
​// 输出false,因为c和d超出了缓存范围,所以它们是不同的对象System.out.println(c == d);}
}
​

在这个例子中,当我们执行Integer a = 100;Integer b = 100;时,由于100在默认的缓存范围内(-128到127),所以ab引用的是同一个Integer对象。因此,当我们使用==比较ab时,结果是true

然而,当我们执行Integer c = 200;Integer d = 200;时,由于200超出了默认的缓存范围,所以cd引用的是两个不同的Integer对象。因此,当我们使用==比较cd时,结果是false

Integer i1 = 40;
Integer i2 = new Integer(40);
//输出false
System.out.println(i1==i2);

Integer i1=40 这一行代码会发生装箱,也就是说这行代码等价于 Integer i1=Integer.valueOf(40) 。因此,i1 直接使用的是缓存中的对象。而Integer i2 = new Integer(40) 会直接创建新的对象。

所有整型包装类对象之间值的比较,全部使用equals比较:因为==比较的是引用的地址,而并非是一个值,如果对象是在缓存范围内产生,那么比较就相同,例如Integer类型在[-127,128]内,就可以在==比较,但是如果在范围之外的所有数据,都会在堆中产生,我们也并不知道是否有缓存存在,所以推荐使用equals比较。

自动装箱与拆箱及其原理

装箱:将基本类型用他们对应的引用类型包装起来。

拆箱:将包装类型转换为基本数据类型。

Integer i = 10;  //装箱
int n = i;   //拆箱

上面这两行代码对应的字节码文件为:

   L1
​LINENUMBER 8 L1
​ALOAD 0
​BIPUSH 10
​INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
​PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;
​L2
​LINENUMBER 9 L2
​ALOAD 0
​ALOAD 0
​GETFIELD AutoBoxTest.i : Ljava/lang/Integer;
​INVOKEVIRTUAL java/lang/Integer.intValue ()I
​PUTFIELD AutoBoxTest.n : I
​RETURN

从字节码中我们发现装箱其实就是调用了包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。

因此,

  • Integer i = 10 等价于 Integer i = Integer.valueOf(10)

  • int n = i 等价于 int n = i.intValue();

如果频繁拆装箱的话,也会严重影响性能,应该避免不变要拆装箱操作。

为什么浮点数运算的时候会有精度丢失的风险?

精度丢失示例:

float a = 2.0f - 1.9f;
float b = 1.8f - 1.7f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999905
System.out.println(a == b);// false

计算机是二进制的,而且计算机在表示一个数字的时候宽度是有限的,无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况,所以就会导致小数精度损失的情况,这就解释了为什么浮点数没有办法用二进制精确表示。

// 0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,
// 在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果。
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)
...

深度了解:计算机系统基础(四)浮点数

如何解决浮点数运算精度丢失问题?

BigDecimal可以实现对浮点数的精确运算,不会造成精度丢失问题,通常情况下大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过BigDecimal来做的

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
BigDecimal c = new BigDecimal("0.8");
​
BigDecimal x = a.subtract(c);
BigDecimal y = b.subtract(c);
​
System.out.println(x); /* 0.2 */
System.out.println(y); /* 0.20 */
// 比较内容,不是比较值
System.out.println(Objects.equals(x, y)); /* false */
// 比较值相等用相等compareTo,相等返回0
System.out.println(0 == x.compareTo(y)); /* true */

超过long整型的数据应该如何表示?

可以使用BigInteger,它可以表示任意精度的整数,BigInteger 支持所有基本的数学运算,并且可以处理比 long 类型更大范围的整数。

变量

成员变量与局部变量的区别?

语法形式:成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数,成员变量可以被publicprivatestatic等修饰符修饰,而局部变量不能被权限修饰符及static所修饰,但是成员变量和局部变量都可以被final所修饰,一经修饰就成为了常量。

存储方式:从变量在内存中的存储方式看,如果成员变量是使用static修饰的,那么这个成员变量是属于类的,在方法区中存储,若没有static修饰,这个成员变量属于对象,存在于堆内存中,局部变量则存在于栈内存

生存时间:从变量在内存中的生存时间看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡。

默认值:从变量是否有默认值来看,成员变量如果没有被赋初始值,则会自动以类型的默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值。

为什么成员变量有默认值?为什么局部变量没有?

  • 成员变量:成员变量属于类的实例,它们在对象创建时分配内存,并在对象的生命周期内持续存在。因此,成员变量可以有一个默认值,这个值在对象创建时自动赋给成员变量,确保了对象状态的完整性。

  • 局部变量:局部变量仅在方法调用或代码块执行时存在,它们的生命周期是短暂的。局部变量的作用域限定在声明它们的代码块内,一旦代码块执行完毕,局部变量就会被销毁。由于局部变量的生命周期如此短暂,自动赋值可能会导致不必要的赋值操作,影响性能,并且可能导致程序员忽略变量的实际用途。

public class VariableExample {// 成员变量private String name;private int age;// 方法中的局部变量public void method() {int num1 = 10; // 栈中分配的局部变量String str = "Hello, world!"; // 栈中分配的局部变量System.out.println(num1);System.out.println(str);}// 带参数的方法中的局部变量public void method2(int num2) {int sum = num2 + 10; // 栈中分配的局部变量System.out.println(sum);}// 构造方法中的局部变量public VariableExample(String name, int age) {this.name = name; // 对成员变量进行赋值this.age = age; // 对成员变量进行赋值int num3 = 20; // 栈中分配的局部变量String str2 = "Hello, " + this.name + "!"; // 栈中分配的局部变量System.out.println(num3);System.out.println(str2);}
}

静态变量有什么作用?

静态变量也就是被 static 关键字修饰的变量。它可以被类的所有实例(对象)共享,无论一个类创建了多少个对象,它们都共享同一份静态变量。也就是说,静态变量只会被分配一次内存,即使创建多个对象,这样可以节省内存。静态变量可以直接通过类名访问,如果被private修饰就不行了。

通常情况下,静态变量会被 final 关键字修饰成为常量。

public class ConstantVariableExample {// 常量public static final int constantVar = 0;
}

字符型常量和字符串常量的区别?

  • 形式 : 字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符。

  • 含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)。

  • 占内存大小:字符常量只占 2 个字节; 字符串常量占若干个字节。

⚠️ 注意 char 在 Java 中占两个字节。

public class StringExample {// 字符型常量public static final char LETTER_A = 'A';// 字符串常量public static final String GREETING_MESSAGE = "Hello, world!";public static void main(String[] args) {System.out.println("字符型常量占用的字节数为:"+Character.BYTES);System.out.println("字符串常量占用的字节数为:"+GREETING_MESSAGE.getBytes().length);}
}

方法

什么是方法的返回值?方法有哪几种类型?

方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!前提是该方法可以产生结果,返回值的作用是接收结果,使得它可以用于其他操作!

静态方法为什么不能调用非静态成员?

结合JVM的知识,主要原因如下:

  1. 静态方法是属于类的,在类加载的时候分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。

  2. 在类的非静态成员不存在的时候静态方法就已经存在了,此时调用在内存中还不存在的非静态成员属于非法操作。

静态方法和实例方法有何不同?

  1. 调用方式:静态方法,也就是经static修饰的方法,可以通过 对象.方法名类名.方法名去调用,调用静态方法可以无需创建对象。但是实例方法必须通过 对象.方法名这种方法去调用。

  2. 静态方法在访问本类的时候,只能访问静态成员(静态方法和静态成员变量),不允许访问实例成员(实例成员变量和实例方法),而实例方法不存在这个限制。

重载和重写的区别?

重载:同样的一个方法能够根据输入数据的不同,做出不同的处理。重载可发生在同一个类中,或父子类之间,但方法名必须相同,参数类型,个数,顺序均不同,方法返回值和访问修饰符可以不同。

//无参构造方法
StringBuilder sb = new StringBuilder();
//有参构造方法
StringBuilder sb2 = new StringBuilder("HelloWorld");
//上述构造方法的方法名相同,但是一个无参一个有参 就发生了方法的重载

所以综上所述,重载就是一个类中多个同名方法根据不同的传参来执行不同的逻辑处理。

重写:重写发生在运行期,是子类对父类的非private方法的实现过程进行重新编写,会有@override注解

  1. 方法名,参数列表必须相同,子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。

  2. 如果父类方法访问修饰符为 private/final/static 则子类就不能重写该方法,但是被 static 修饰的方法能够被再次声明。

  3. 构造方法无法被重写

所以综上所述,重写就是子类对父类方法的重新改造,外部样子不能改变,内部逻辑可以改变。

需要注意的是:如果方法的返回类型是 void 和基本数据类型,则返回值重写时不可修改。但是如果方法的返回值是引用类型,重写时是可以返回该引用类型的子类的。

什么是可变长参数?

所谓可变长参数就是允许在调用方法时传入不定长度的参数。就比如下面这个方法就可以接受 0 个或者多个参数。

public static void method1(String... args) {//......
}

另外,可变参数只能作为函数的最后一个参数,但其前面可以有也可以没有任何其他参数。

public static void method2(String arg1, String... args) {//......
}

遇到方法重载,会优先匹配固定参数的方法,因为固定参数的方法匹配度更高。

public class VariableLengthArgument {public static void printVariable(String... args) {for (String s : args) {System.out.println(s);}}public static void printVariable(String arg1, String arg2) {System.out.println(arg1 + arg2);}public static void main(String[] args) {printVariable("a", "b");printVariable("a", "b", "c", "d");}
}

输出:

ab
a
b
c
d

另外,Java 的可变参数编译后实际会被转换成一个数组,我们看编译后生成的 class文件就可以看出来了。

public class VariableLengthArgument {public static void printVariable(String... args) {String[] var1 = args;int var2 = args.length;for(int var3 = 0; var3 < var2; ++var3) {String s = var1[var3];System.out.println(s);}}// ......
}

(详情请参考:Java集合使用注意事项总结 | JavaGuide)

相关文章:

Java基础总结上(Ref:JavaGuide)

基础概念与常识 Java语言有哪些特点&#xff0c;优点&#xff1f; 简单易学&#xff0c;是一门面向对象的语言&#xff0c;有封装继承多态三大特性&#xff0c;而且有多重防护机制保证安全性&#xff0c;例如权限修饰符&#xff0c;限制程序直接访问操作系统资源。通过JIT编译…...

嘉誉府5区共有产权看房记

特地工作日来看下嘉誉府5区的网红共有产权的房子&#xff0c;主要是冲着均价2.1万/平才来看。说实话从塘尾地铁步行到嘉誉府5区还挺需要时间的哈。可能以后需要电驴代步到地铁&#xff1f;确实楼盘现在是现楼&#xff0c;今年买明年住。鸿荣源确实很666哈。 今天来不需要排队&a…...

PostgreSQL函数中使用now()或current_timestamp的异同

在PostgreSQL函数中使用now()或current_timestamp可以获取当前的日期和时间。 now()函数返回当前的日期和时间&#xff0c;包括时区信息。它可以用于记录操作的时间戳或在查询中进行时间比较。 current_timestamp函数也返回当前的日期和时间&#xff0c;但不包括时区信息。它…...

跟李笑来学美式俚语(Most Common American Idioms): Part 56

Most Common American Idioms: Part 56 前言 本文是学习李笑来的Most Common American Idioms这本书的学习笔记&#xff0c;自用。 Github仓库链接&#xff1a;https://github.com/xiaolai/most-common-american-idioms 使用方法: 直接下载下来&#xff08;或者clone到本地…...

类和对象一

目录 1.类的引入 2.类的定义 3.访问限定符 4.类的作用域 5.类对象模型 6.类的大小 1.类的引入 C语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体不仅可以定义变量&#xff0c;也可以定义函数。 C兼容C语言&#xff0c;结构用法可以继续使用 同时sruct也升…...

两个数的和最小

两个数的和最小 C 代码C 代码Java 代码Python 代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给你n个整数&#xff0c;你可以从中任意取两个数a和b&#xff0c;问a加上b的和的绝对值最小可能是多少&#xff1f; 输入 有多组测试数据…...

Mac mini m4本地跑大模型(ollama + llama + ComfyUI + Stable Diffusion | flux)

安装chat大模型&#xff08;不推荐&#xff0c;本地运行的大模型只能聊废话&#xff0c;不如网页版使用openAI等高效&#xff09; 首先下载ollama的安装包 https://ollama.com/ 点击启动访问&#xff1a;http://localhost:11434 Ollama is running 代表已经运行起来了&#x…...

IoTDB AINode 报错,call inference 301: Error ocurred while executing inference

问题及现象 使用时序数据库 IoTDB 的 AINode 的 call inference 语句后报错&#xff1a; Msg: org.apache.iotdb.jdbc.IoTDBSOLException&#xff1a;301: Error ocurred while executing inference:[tuple object has no attribute inference]解决方法 可以替换 venv 里面的…...

Linux网络 UDP socket

背景知识 我们知道&#xff0c; IP 地址用来标识互联网中唯一的一台主机&#xff0c; port 用来标识该主机上唯一的一个网络进程&#xff0c;IPPort 就能表示互联网中唯一的一个进程。所以通信的时候&#xff0c;本质是两个互联网进程代表人来进行通信&#xff0c;{srcIp&…...

Day2——需求分析与设计

教师端签到应用软件的需求分析&#xff1b; 产品经理如何写好产品需求文档&#xff08;附模板&#xff09; 需求分析是软件开发过程中的关键步骤&#xff0c;它确保了开发的软件能够满足用户的需求。以下是进行需求分析的具体步骤&#xff1a; 1. 确定分析目标 明确教师端签到…...

aosp15上winscope离线html如何使用?

背景&#xff1a; aosp15上的如何使用Winscope前面已经有分享过相关的blog&#xff0c;这块其实和aosp14没啥大的差别&#xff0c;具体可以看如下2个文章&#xff1a; 手把手教你aosp14编译Winscope 安卓aosp15手机上如何离线获取winscope文件 文章中也说明在aosp15如果直接使…...

AttributeError: module numpy has no attribute int .报错解决

AttributeError: module numpy has no attribute int .报错解决方案_attributeerror: module numpy has no attribute i-CSDN博客 以上为参考教程&#xff0c;试了卸载再安装&#xff0c;不行&#xff0c;报错&#xff1a; Found existing installation: numpy 1.24.3 error: …...

python爬虫常用数据保存模板(Excel、CSV、mysql)——scrapy中常用数据提取方法(CSS、XPATH、正则)(23)

文章目录 1、常用数据保存模板2.1 保存为Excel格式2.2 保存为CSV格式2.3 保存至mysql数据库2、scrapy中常用数据提取方法2.1 XPath选择器2.2 CSS选择器2.3 正则表达式1、常用数据保存模板 2.1 保存为Excel格式 # 1、导入模块 from openpyxl import workbook# 2、创建一个exce…...

【面试题】简述rabbitmq的组织架构

[面试题]简述rabbitmq的组织架构 RabbitMQ 是一种流行的消息中间件&#xff0c;其架构设计围绕消息生产者, 消息消费者和消息中转&#xff08;Broker&#xff09;展开。以下是 RabbitMQ 的主要组织架构组件和它们之间的关系&#xff1a; 1. 核心组件 1.1 Producer&#xff0…...

C#-WPF 常见类型转换方法(持续更新)

目录 一、普通类型转换 1、Convert类 2、Parse(转String) 3、TryParse(转String) 4、ToString(转String) 5、int转double 6、String转DateTime 7、自定义类型的显示/隐式转换 二、byte[]转ImageSource 方法一 方法二 一、普通类型转换 1、Convert类 提供了一种安全…...

c基础加堆练习题

1】思维导图&#xff1a; 2】在堆区空间连续申请5个int类型大小空间&#xff0c;用来存放从终端输入的5个学生成绩&#xff0c;然后显示5个学生成绩&#xff0c;再将学生成绩升序排序&#xff0c;排序后&#xff0c;再次显示学生成绩。显示和排序分别用函数完成 要求&#xff…...

做了一份前端面试复习计划,保熟~

前言 以前我看到面试贴就直接刷掉的&#xff0c;从不会多看一眼&#xff0c;直到去年 9 月份我开始准备面试时&#xff0c;才发现很多面试经验贴特别有用&#xff0c;看这些帖子&#xff08;我不敢称之为文章&#xff0c;怕被杠&#xff09;的过程中对我的复习思维形成影响很大…...

虚幻引擎开发命名规则

UE的命名规则如下&#xff1a; 模版类以T作为前缀&#xff0c;例如TArray, TMap, TSet。UObject派生类都以U前缀。AActor派生类都以A前缀。SWidget派生类都以S前缀。全局对象使用G开头&#xff0c;如GEngine。抽象接口以I前缀。枚举以E开头。bool变量以b前缀&#xff0c;如bPe…...

【蓝桥杯每日一题】砍竹子

砍竹子 2024-12-7 蓝桥杯每日一题 砍竹子 STL 贪心 题目大意 这天, 小明在砍竹子, 他面前有 nn 棵竹子排成一排, 一开始第 ii 棵竹子的 高度为 h i h_i hi​. 他觉得一棵一棵砍太慢了, 决定使用魔法来砍竹子。魔法可以对连续的一 段相同高度的竹子使用, 假设这一段竹子的高度为…...

Lambda表达式随记

学习链接 目录 作用定义[capture list] 捕获列表(paramter) 参数列表mutable 可变规格throw() 异常说明-> return-type 返回类型{function statement} lambda函数体 Lambda表达式的优缺点Lambda表达式工作原理适用场景STL算法库短小不需要复用函数场景 作用 Lambda表达式&…...

Vulhub:Log4j[漏洞复现]

CVE-2017-5645(Log4j反序列化) 启动靶场环境 docker-compose up -d 靶机IPV4地址 ifconfig | grep eth0 -A 5 ┌──(root㉿kali)-[/home/kali/Desktop/temp] └─# ifconfig | grep eth0 -A 5 eth0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 in…...

ubuntu系统生成SSL证书配置https

自签名【Lets Encrypt】的测试证书&#xff0c;有效期三个月。 第一步&#xff1a;安装acme&#xff0c;如果没有安装git&#xff0c;需要提前安装 下载came资源 git clone https://github.com/Neilpang/acme.sh.git 无法访问&#xff0c;可以试用gitee的资源&#xff0c;安…...

记录 idea 启动 tomcat 控制台输出乱码问题解决

文章目录 问题现象解决排查过程1. **检查 idea 编码设置**2. **检查 tomcat 配置**3.检查 idea 配置文件4.在 Help 菜单栏中&#xff0c;修改Custom VM Options完成后保存&#xff0c;并重启 idea 问题现象 运行 tomcat 后&#xff0c;控制台输出乱码 解决排查过程 1. 检查 id…...

C++ unordered_map和unordered_set的使用

1.unordered_set系列的使用 1.1unordered_set和unordered_multiset参考文档 unordered_set和unordered_multiset参考文档 1.2unordered_set类的介绍 • unordered_set的声明如下&#xff0c;Key就是unordered_set底层关键字的类型 • unordered_set默认要求Key⽀持转换为整…...

【探商宝】OpenAI 发布 Sora:视频生成领域的重大突破

2024 年 12 月 10 日&#xff0c;OpenAI 正式推出了备受瞩目的人工智能视频生成模型 Sora&#xff0c;这一举措在科技界引起了轩然大波&#xff0c;为视频创作领域带来了全新的可能性和变革. 一、Sora 的功能与特性 1. 强大的视频生成能力 Sora 能够根据用户输入的文本描述生…...

[代码随想录Day32打卡] 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

理论基础 题型 动归基础&#xff08;这一节就是基础题&#xff09;背包问题打家劫舍股票问题子序列问题 动态规划五部曲 确定dp数组及其下标的含义确定递推公式dp数组如何初始化遍历顺序打印dp数组 509. 斐波那契数 简单~ dp数组及下标含义&#xff1a; dp[i]表示第i各斐…...

【实操GPT-SoVits】声音克隆模型图文版教程

项目github地址&#xff1a;https://github.com/RVC-Boss/GPT-SoVITS.git官方教程&#xff1a;https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/tkemqe8vzhadfpeu本文旨在迅速实操GPT-SoVits项目&#xff0c;不阐述技术原理&#xff08;后期如果有时间研究&#…...

开发一套SDK 第一弹

自动安装依赖包 添加条件使能 #ex: filetypesh bash_ls 识别 达到预期,多个硬件环境 等待文件文件系统挂在完成 或者创建 /sys/class/ 属性文件灌入配置操作 AI 提供的 netlink 调试方法,也是目前主流调用方法,socket yyds #include <linux/module.h> #include <linux…...

2024149读书笔记|Hans的阿狸五部曲——成长的路上分离在所难免

2024149读书笔记|Hans的阿狸五部曲——成长的路上分离在所难免 1. 《阿狸和小小云》2. 《阿狸和小玉》3. 《阿狸呓语》4. [202480读书笔记|《阿狸和弯月亮》——生的再普通&#xff0c;也是限量版](https://blog.csdn.net/qq_40985985/article/details/139731131)5. 《阿狸永远…...

外包干了5天,技术明显退步。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...

Ubuntu22.04 安装Isaac Lab

目录 1.1 安装IsaacLab 1.1.1 下载文件 1.1.2 创建Isaac Sim符号链接 1.1.3 创建并激活conda环境 1.1.4 安装依赖 1.1.5 安装IsaacLab扩展 1.1.6 安装完成&#xff0c;要source一下 1.2 验证IsaacLab安装 1.1 安装IsaacLab 1.1.1 下载文件 将 Isaac Lab 仓库克隆到您的…...

unity 2D像素种田游戏学习记录(自用)

一、透明度排序轴 改变sprite的排序方式&#xff0c;默认按照z轴进行排序&#xff08;离摄像机的远近&#xff09;。可以将其改变成y轴的排序方式&#xff0c;这样可以使2D人物走在草丛的下方就不被遮挡&#xff0c;走在草丛上方就被遮挡&#xff0c;如下图。 在项目设置-图形…...

NIFI使用

1 从Kafka接收消息&#xff0c;存储到数据库中。 &#xff08;1&#xff09; ConsumerKafka processor &#xff08;2&#xff09;Execute Scripts Processor 我这里是使用JS脚本进行处理。 还有很多其他语言的脚本。 var flowFile session.get(); if (flowFile ! null) {v…...

vue3+vite+ts 使用webrtc-streamer播放海康rtsp监控视频

了解webrtc-streamer webrtc-streamer 是一个使用简单机制通过 WebRTC 流式传输视频捕获设备和 RTSP 源的项目&#xff0c;它内置了一个小型的 HTTP server 来对 WebRTC需要的相关接口提供支持。相对于ffmpegflv.js的方案&#xff0c;延迟降低到了0.4秒左右&#xff0c;画面的…...

Nanolog起步笔记-9-log解压过程(3)寻找meta续

Nanolog起步笔记-9-log解压过程-3-寻找meta续 当前的目标新的改变decompressNextLogStatementmetadata查看业务面的log语句注释掉 runBenchmark();改过之后&#xff0c;2条记录之后&#xff0c;这里就直接返回了 小结 当前的目标 没有办法&#xff0c;还要继续。 当前的目标&a…...

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…...

【北京迅为】iTOP-4412全能版使用手册-第六十八章 U-boot基础知识

iTOP-4412全能版采用四核Cortex-A9&#xff0c;主频为1.4GHz-1.6GHz&#xff0c;配备S5M8767 电源管理&#xff0c;集成USB HUB,选用高品质板对板连接器稳定可靠&#xff0c;大厂生产&#xff0c;做工精良。接口一应俱全&#xff0c;开发更简单,搭载全网通4G、支持WIFI、蓝牙、…...

go 中线程安全map

在 Go 语言中&#xff0c;官方包 sync.Map 确实提供了线程安全的映射数据结构。然而&#xff0c;正如你所提到的&#xff0c;使用 sync.Map 时&#xff0c;有时需要进行类型断言&#xff0c;这可能会让代码显得冗长或不直观。 如果你希望使用一个更加易用的线程安全映射&#…...

封装类与普通类的区别

1 封装类的好处 数据隐藏&#xff1a;通过封装&#xff0c;我们可以将类的内部实现细节隐藏起来&#xff0c;只暴露有限的接口。这样&#xff0c;外部代码就不能直接访问或修改类的内部状态&#xff0c;从而保证了数据的安全性和完整性。 数据保护&#xff1a;封装可以…...

StarRocks-hive数据类型导致的分区问题

背景&#xff1a; 有个hive的表&#xff0c;是月分区的&#xff08;month_id&#xff09;&#xff0c;分区字段用的是string类型。数据量比较大&#xff0c;为了保证计算性能&#xff0c;所以把数据导入到SR里&#xff0c;构建一个内部表。但是在建表的时候想使用月分区使用pa…...

Java面试题精选:设计模式(二)

1、装饰器模式与代理模式的区别 1&#xff09;代理模式(Proxy Design Pattern ) 原始定义是&#xff1a;让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问&#xff0c;并允许将请求提交给对象前后进行一些处理。 代理模式的适用场景 功能增强 当需要对一个对…...

【JavaEE】多线程(7)

一、JUC的常见类 JUC→java.util.concurrent&#xff0c;放了和多线程相关的组件 1.1 Callable 接口 看以下从计算从1加到1000的代码&#xff1a; public class Demo {public static int sum;public static void main(String[] args) throws InterruptedException {Thread …...

技术型企业如何高效搭建企业博客以增强品牌影响力和市场竞争力

在数字化时代&#xff0c;技术型企业面临着激烈的市场竞争和快速变化的行业环境。为了在这场竞争中脱颖而出&#xff0c;企业需要寻找新的营销渠道和品牌建设工具。企业博客作为一种低成本、高效率的在线内容平台&#xff0c;已经成为技术型企业增强品牌影响力和市场竞争力的重…...

【qt环境配置】windows下的qt与vs工具集安装\版本对应关系

vs工具集安装通过vs的在线安装器勾选工具集即可 工具包下载路径&#xff1a;https://www.microsoft.com/zh-cn/download/details.aspx?id40784 配置工具集在qt中可以自动扫描到 《正确在 Windows 上配置 MSVC(2019) 作为 Qt 编译器》https://b3logfile.com/pdf/article/15922…...

XTuner 微调实践微调

步骤 0. 使用 conda 先构建一个 Python-3.10 的虚拟环境 cd ~ #git clone 本repo git clone https://github.com/InternLM/Tutorial.git -b camp4 mkdir -p /root/finetune && cd /root/finetune conda create -n xtuner-env python3.10 -y conda activate xtuner-env…...

docker compose

Docker的理念是一个容器只运行一个服务。而 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具 1 2。通过 docker-compose.yml 文件&#xff0c;用户可以配置应用程序服务&#xff0c;并使用简单的一条命令便可以创建和启动所有服务。这是关于 Docker Compose …...

Java 中的方法重写

在 Java 中&#xff0c;方法重写&#xff08;Method Overriding&#xff09;是面向对象编程的一个重要概念&#xff0c;它指的是子类中存在一个与父类中相同名称、相同参数列表和相同返回类型的方法。方法重写使得子类可以提供特定的实现&#xff0c;从而覆盖&#xff08;或改变…...

阿里云ECS服务器域名解析

阿里云ECS服务器域名解析&#xff0c;以前添加两条A记录类型&#xff0c;主机记录分别为www和&#xff0c;这2条记录都解析到服务器IP地址。 1.进入阿里云域名控制台&#xff0c;找到域名 ->“解析设置”->“添加记录” 2.添加一条记录类型为A,主机记录为www&#xff0c…...

非父子通信(扩展)-- event bus 事件总线

创建一个空实例Bus&#xff0c; export default 导出Bus 过程:由A组件对Bus组件进行监听&#xff0c;B组件触发Bus对应的事件&#xff0c;由于A组件进行监听&#xff0c;触发事件之后就会进行A组件的回调&#xff0c;那么就可以将消息发送给A了 在src文件夹下新建utils文件夹&a…...

【Linux系列】获取当前目录

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...