Java基础(中)
变量
成员变量与局部变量的区别
-
语法形式:从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可以被
public
,private
,static
等修饰符所修饰,而局部变量不能被访问控制修饰符及static
所修饰;但是,成员变量和局部变量都能被final
所修饰。 -
存储方式:从变量在内存中的存储方式来看,如果成员变量是使用
static
修饰的,那么这个成员变量是属于类的,如果没有使用static
修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存。 -
生存时间:从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡。
-
默认值:从变量是否有默认值来看,成员变量如果没有被赋初始值,则会自动以类型的默认值而赋值(一种情况例外:被
final
修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值。
那为什么成员变量要有默认值呢?
-
因为如果不给成员变量默认值,而是指向随机内存中的一块区域,在读取该值的时候就会报错
-
默认值有两种设置方式:手动和自动,根据第一点,没有手动赋值一定要自动赋值。成员变量在运行时可借助反射等方法手动赋值,而局部变量不行
-
对于编译器(javac)来说,局部变量没赋值很好判断,可以直接报错。而成员变量可能是运行时赋值,无法判断,误报“没默认值”又会影响用户体验,所以采用自动赋默认值
静态变量又有什么作用呢?
所谓静态变量就是被static关键字修饰的变量,这个变量被类的所有实例所共享,无论有多少实例,它们共享的都是同一份静态变量,在JVM运行时只为静态变量分配一次内存,这样一来就算实例很多,也不用重复创建,节省内存
静态变量可以通过 类名.变量名的方式直接访问(此变量被private访问修饰符修饰就不行)
通常情况下,静态变量会被final修饰成常量使用
public class ConstantVariableExample {// 常量public static final int constantVar = 0;
}
字符型常量和字符串常量的区别?
-
形式 : 字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符。
-
含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)。
-
占内存大小:字符常量只占 2 个字节; 字符串常量占若干个字节。
注意
char
在 Java 中占两个字节
方法
静态方法为什么不能调用非静态成员?
结合JVM知识来说,静态方法是属于类的,在类加载时分配内存就存在了,而非静态的成员是依赖于类的实例的,用一个早就存在的方法去调用一个目前在内存中不存在的成员这种操作是非法的,也调用不了
静态方法和实例方法有何不同?
1.调用方式
静态方法的调用方式有两种,可以通过类名.方法名的方式调用,也可以通过创建类实例,使用对象名.方法名的方式调用,而实例方法只能通过后者的方式调用
但是一般情况下都用类名.方法名的方式调用,因为用第二种方式的话容易混淆
2.类成员的访问方式
静态方法只能访问静态类成员(静态变量、静态方法),实例成员无法访问(实例变量、实例方法),而实例方法不受限制
重载
发生在同一个类中(或者父类和子类之间),方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同
编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配来挑选出相应的方法。 如果编译器找不到匹配的参数, 就会产生编译时错误, 因为根本不存在匹配, 或者没有一个比其他的更好(这个过程被称为重载解析(overloading resolution))
Java 允许重载任何方法, 而不只是构造器方法。
重写
重写发生在运行期,是子类对父类的允许访问的方法的实现过程进行重新编写。
-
方法名、参数列表必须相同,子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
-
如果父类方法访问修饰符为
private/final/static
则子类就不能重写该方法,但是被static
修饰的方法能够被再次声明。 -
构造方法无法被重写
重载和重写有什么区别?
重载就是同样的一个方法能够根据输入数据的不同,做出不同的处理
重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法
区别点 | 重载方法 | 重写方法 |
---|---|---|
发生范围 | 同一个类 | 子类 |
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可修改 | 子类方法返回值类型应比父类方法返回值类型更小或相等 |
异常 | 可修改 | 子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等; |
访问修饰符 | 可修改 | 一定不能做更严格的限制(可以降低限制) |
发生阶段 | 编译期 | 运行期 |
可变长参数
从 Java5 开始,Java 支持定义可变长参数,所谓可变长参数就是允许在调用方法时传入不定长度的参数。就比如下面这个方法就可以接受 0 个或者多个参数
可变参数只能作为函数的最后一个参数,但其前面可以有也可以没有任何其他参数
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 的可变参数编译后实际会被转换成一个数组
面向对象
面向对象和面向过程的区别
面向过程编程(Procedural-Oriented Programming,POP)和面向对象编程(Object-Oriented Programming,OOP)是两种常见的编程范式,两者的主要区别在于解决问题的方式不同
-
面向过程编程(POP):面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。
-
面向对象编程(OOP):面向对象会先抽象出对象,然后用对象执行方法的方式解决问题。
相比较于 POP,OOP 开发的程序一般具有下面这些优点:
-
易维护:由于良好的结构和封装性,OOP 程序通常更容易维护。
-
易复用:通过继承和多态,OOP 设计使得代码更具复用性,方便扩展功能。
-
易扩展:模块化设计使得系统扩展变得更加容易和灵活。
POP 的编程方式通常更为简单和直接,适合处理一些较简单的任务
POP 和 OOP 的性能差异主要取决于它们的运行机制,而不仅仅是编程范式本身,如果只是简单地去比较两者的性能差异是一种误区,面向过程也需要分配内存、计算内存偏移量,Java性能较差的原因并不只是因为它是面向对象这么简单,而是因为Java本身是一种半编译语言,最终的执行代码并不是可以直接被CPU执行的二进制机械码,而面向过程的语言一般都是直接编译成二进制的机械码,一些面向过程的脚本语言性能也不见得比Java好
在选择编程范式时,性能并不是唯一的考虑因素。代码的可维护性、可扩展性和开发效率同样重要。
现代编程语言基本都支持多种编程范式,既可以用来进行面向过程编程,也可以进行面向对象编程。
创建一个对象用什么运算符?对象实体与对象引用有何不同
创建对象通常使用new关键字,new关键字创建对象实例(对象实例存放在堆内存中),而对象的引用指向对象的实例(对象引用存放在栈内存中)
-
一个对象引用可以指向 0 个或 1 个对象(一对一);
-
一个对象可以有 n 个引用指向它(一对多)
面向对象三大特征
封装
封装是指把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外界访问的方法来操作属性。就好像我们看不到挂在墙上的空调的内部的零件信息(也就是属性),但是可以通过遥控器(方法)来控制空调。如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。就好像如果没有空调遥控器,那么我们就无法操控空凋制冷,空调本身就没有意义了(当然现在还有很多其他方法 ,这里只是为了举例子)
继承
不同类型的对象,相互之间经常有一定数量的共同点。例如,张三、李四、王五,都共享人的特性(体重、身高等)。同时,每一个对象还定义了额外的特性使得他们与众不同。例如张三比较重,李四又比较轻;王五又比较高。继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承,可以快速地创建新的类,可以提高代码的重用,程序的可维护性,节省大量创建新类的时间 ,提高我们的开发效率
注意:
子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。
子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
多态
多态,顾名思义,表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。
-
对象类型和引用类型之间具有继承(类)/实现(接口)的关系;
-
引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;
-
多态不能调用“只在子类存在但在父类不存在”的方法;
-
如果子类重写了父类的方法,真正执行的是子类重写的方法,如果子类没有重写父类的方法,执行的是父类的方法。
深拷贝和浅拷贝区别了解吗?什么是引用拷贝?
-
浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。
-
深拷贝:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。
那什么是引用拷贝呢? 简单来说,引用拷贝就是两个不同的引用指向同一个对象
浅拷贝、深拷贝、引用拷贝的原理:
Object
Object 类的常见方法
/*** native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。*/
public final native Class<?> getClass()
/*** native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。*/
public native int hashCode()
/*** 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等。*/
public boolean equals(Object obj)
/*** native 方法,用于创建并返回当前对象的一份拷贝。*/
protected native Object clone() throws CloneNotSupportedException
/*** 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。*/
public String toString()
/*** native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。*/
public final native void notify()
/*** native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。*/
public final native void notifyAll()
/*** native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间。*/
public final native void wait(long timeout) throws InterruptedException
/*** 多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。。*/
public final void wait(long timeout, int nanos) throws InterruptedException
/*** 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念*/
public final void wait() throws InterruptedException
/*** 实例被垃圾回收器回收的时候触发的操作*/
protected void finalize() throws Throwable { }
hashCode() 有什么用
hashCode()
的作用是获取哈希码(int
整数),也称为散列码。这个哈希码的作用是确定该对象在哈希表中的索引位置
hashCode()
定义在 JDK 的Object
类中,这就意味着 Java 中的任何类都包含有hashCode()
函数。另外需要注意的是:Object
的hashCode()
方法是本地方法,也就是用 C 语言或 C++ 实现的该方法在 Oracle OpenJDK8 中默认是 "使用线程局部状态来实现 Marsaglia's xor-shift 随机数生成", 并不是 "地址" 或者 "地址转换而来", 不同 JDK/VM 可能不同在 Oracle OpenJDK8 中有六种生成方式 (其中第五种是返回地址), 通过添加 VM 参数: -XX:hashCode=4 启用第五种。参考源码:
jdk8u/jdk8u/hotspot: 87ee5ee27509 src/share/vm/runtime/globals.hpp(1127 行)
jdk8u/jdk8u/hotspot: 87ee5ee27509 src/share/vm/runtime/synchronizer.cpp(537 行开始)
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
那为什么要有 hashCode呢?
equals方法中就重写了hashCode方法,我们在比较两个对象是否相等时,通过哈希算法计算出他们的哈希值看是否相等,然而这只是一个前提条件,哈希值相同的两个对象不一定相等,因为有哈希碰撞这一情况,即可能有多个对象传回的Hash值相同,越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓哈希碰撞也就是指的是不同的对象得到相同的 hashCode
),这也是为什么JDK要提供equals和hashCode这两个方法的原因,并且在一些容器中(HashSet、HashMap),使用hashCode能大大缩小查找的成本,判断元素是否在对应容器中的效率会更高
当你把对象加入
HashSet
时,HashSet
会先计算对象的hashCode
值来判断对象加入的位置,同时也会与其他已经加入的对象的hashCode
值作比较,如果没有相符的hashCode
,HashSet
会假设对象没有重复出现。但是如果发现有相同hashCode
值的对象,这时会调用equals()
方法来检查hashCode
相等的对象是否真的相同。如果两者相同,HashSet
就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了equals
的次数,相应就大大提高了执行速度
总结下来就是:
-
如果两个对象的
hashCode
值相等,那这两个对象不一定相等(哈希碰撞)。 -
如果两个对象的
hashCode
值相等并且equals()
方法也返回true
,我们才认为这两个对象相等。 -
如果两个对象的
hashCode
值不相等,我们就可以直接认为这两个对象不相等
String
String、StringBuffer、StringBuild之间的区别
可变性
String
:线程安全且不可变的
StringBuilder
与 StringBuffer
都继承自 AbstractStringBuilder
类,在 AbstractStringBuilder
中也是使用字符数组保存字符串,不过没有使用 final
和 private
关键字修饰,最关键的是这个 AbstractStringBuilder
类还提供了很多修改字符串的方法比如 append
方法
线程安全性
String
中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder
是 StringBuilder
与 StringBuffer
的公共父类,定义了一些字符串的基本操作,如 expandCapacity
、append
、insert
、indexOf
等公共方法。StringBuffer
对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder
并没有对方法进行加同步锁,所以是非线程安全的。
性能
每次对 String
类型进行改变的时候,都会生成一个新的 String
对象,然后将指针指向新的 String
对象。StringBuffer
每次都会对 StringBuffer
对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder
相比使用 StringBuffer
仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
对于三者使用的总结:
-
操作少量的数据: 适用
String
-
单线程操作字符串缓冲区下操作大量数据: 适用
StringBuilder
-
多线程操作字符串缓冲区下操作大量数据: 适用
StringBuffer
String 为什么是不可变的?
String
类中使用 final
关键字修饰字符数组来保存字符串,我们知道被 final
关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是基本数据类型则值不能改变,修饰的变量是引用类型则不能再指向其他对象。因此,final
关键字修饰的数组保存字符串并不是 String
不可变的根本原因,因为这个数组保存的字符串是可变的(final
修饰引用类型变量的情况)
String
真正不可变有下面几点原因:
-
保存字符串的数组被
final
修饰且为私有的,并且String
类没有提供/暴露修改这个字符串的方法。 -
String
类被final
修饰导致其不能被继承,进而避免了子类破坏String
不可变。
在 Java 9 之后,
String
、StringBuilder
与StringBuffer
的实现改用byte
数组存储字符串,新版的 String 其实支持两个编码方案:Latin-1 和 UTF-16。如果字符串中包含的汉字没有超过 Latin-1 可表示范围内的字符,那就会使用 Latin-1 作为编码方案。Latin-1 编码方案下,byte
占一个字节(8 位),char
占用 2 个字节(16),byte
相较char
节省一半的内存空间JDK 官方就说了绝大部分字符串对象只包含 Latin-1 可表示的字符
字符串拼接用“+” 还是 StringBuilder?
其实Java
语言本身并不支持运算符重载,“+”和“+=”是专门为 String
类重载过的运算符,也是Java
中仅有的两个重载过的运算符
字符串对象通过“+”的字符串拼接方式,实际上是通过 StringBuilder
调用 append()
方法实现的,拼接完成之后调用 toString()
得到一个 String
对象 。
不过,在循环内使用“+”进行字符串的拼接的话,存在比较明显的缺陷:编译器不会创建单个 StringBuilder
以复用,会导致创建过多的 StringBuilder
对象
如果直接使用 StringBuilder
对象进行字符串拼接的话,就不会存在这个问题了
在 JDK 9 中,字符串相加“+”改为用动态方法
makeConcatWithConstants()
来实现,通过提前分配空间从而减少了部分临时对象的创建。然而这种优化主要针对简单的字符串拼接,如:a+b+c
。对于循环中的大量拼接操作,仍然会逐个动态分配内存(类似于两个两个 append 的概念),并不如手动使用 StringBuilder 来进行拼接效率高。这个改进是 JDK9 的 JEP 280 提出的,关于这部分改进的详细介绍,推荐阅读这篇文章:还在无脑用 StringBuilder?来重温一下字符串拼接吧 以及参考 issue#2442。
String#equals() 和 Object#equals() 有何区别
String
中的 equals
方法是被重写过的,比较的是 String 字符串的值是否相等。 Object
的 equals
方法是比较的对象的内存地址
字符串常量池的作用
字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建
// 在字符串常量池中创建字符串对象 ”ab“
// 将字符串对象 ”ab“ 的引用赋值给 aa
String aa = "ab";
// 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb
String bb = "ab";
System.out.println(aa==bb); // true
String#intern 方法
String.intern()
是一个 native
(本地) 方法,用来处理字符串常量池中的字符串对象引用。它的工作流程可以概括为以下两种情况:
-
常量池中已有相同内容的字符串对象:如果字符串常量池中已经有一个与调用
intern()
方法的字符串内容相同的String
对象,intern()
方法会直接返回常量池中该对象的引用 -
常量池中没有相同内容的字符串对象:如果字符串常量池中还没有一个与调用
intern()
方法的字符串内容相同的对象,intern()
方法会将当前字符串对象的引用添加到字符串常量池中,并返回该引用
总结:
-
intern()
方法的主要作用是确保字符串引用在常量池中的唯一性 -
当调用
intern()
时,如果常量池中已经存在相同内容的字符串,则返回常量池中已有对象的引用;否则,将该字符串添加到常量池并返回其引用
String 类型的变量和常量做“+”运算时发生了什么
字符串不加 final
关键字拼接的情况(JDK1.8)
String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
String str5 = "string";
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false
对于编译期可以确定值的字符串,也就是常量字符串 ,jvm 会将其存入字符串常量池。并且,字符串常量拼接得到的字符串常量在编译阶段就已经被存放字符串常量池,这个得益于编译器的优化
在编译过程中,Javac 编译器(下文中统称为编译器)会进行一个叫做 常量折叠(Constant Folding) 的代码优化,常量折叠会把常量表达式的值求出来作为常量嵌在最终生成的代码中,这是 Javac 编译器会对源代码做的极少量优化措施之一(代码优化几乎都在即时编译器中进行)
对于 String str3 = "str" + "ing";
编译器会给你优化成 String str3 = "string";
引用的值在程序编译期是无法确定的,编译器无法对其进行优化。
对象引用和“+”的字符串拼接方式,实际上是通过 StringBuilder
调用 append()
方法实现的,拼接完成之后调用 toString()
得到一个 String
对象
String str4 = new StringBuilder().append(str1).append(str2).toString();
所以说我们在平时写代码的时候,尽量避免多个字符串对象拼接,因为这样会重新创建对象。如果需要改变字符串的话,可以使用 StringBuilder
或者 StringBuffer
但是,字符串使用 final
关键字声明之后,可以让编译器当做常量来处理,被 final
关键字修饰之后的 String
会被编译器当做常量来处理,编译器在程序编译期就可以确定它的值,其效果就相当于访问常量。如果 ,编译器在运行时才能知道其确切值的话,就无法对其优化
final String str1 = "str";
final String str2 = getStr();
String c = "str" + "ing";// 常量池中的对象
String d = str1 + str2; // 在堆上创建的新的对象
System.out.println(c == d);// false
public static String getStr() {return "ing";
}
相关文章:

Java基础(中)
变量 成员变量与局部变量的区别 语法形式:从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控…...

Leetcode热题100-200 岛屿数量
Leetcode热题100-200 岛屿数量 1. 题目描述2. 代码实现1. dfs算法2. bfs算法 1. 题目描述 200 岛屿数量 2. 代码实现 1. dfs算法 class Solution { public:int numIslands(vector<vector<char>>& grid) {int m grid.size(), n grid[0].size();int res 0…...

大数据新视界 --大数据大厂之 GraphQL 在大数据查询中的创新应用:优化数据获取效率
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

swift使用代码结构解析
多模态模型的训练llamafactory也可以训练,但是总的来说,llamafactory对多模态模型的支持还是不太多,ms-swift支持的多模态模型更多,因此有时候去找框架是否够支持相应的模型时会有所困难,所以对这些框架的代码也要稍微…...

五、Python基础语法(程序的输入和输出)
一、输入 输入:输入就是获取键盘输入的数据,使用input()函数。代码会从上往下执行,当遇到input()函数,就会暂停执行,输入内容后,敲回车键,表示本次的输入结束。input函数得到的数据类型都是字符…...

【C语言】常见概念
文章目录 库函数关键字字符和ASCll编码字符串与\0转义字符语句和语句分类注释 库函数 为了不再重复实现常见的代码,让程序员提升开发效率,C语言标准规定了一组函数,这些函数再由不同的编译器厂商根据标准进行实现,提供给程序员使…...

Electron应用创建和打包
一、创建项目目录 创建NodeJs项目目录,项目有关的文件、依赖包都将在本目录创建和安装。 mkdir hello_electron & cd hello_electronCMD执行以上命令将在用户目录下创建hello_electron并进入该目录。当然也可以手动在任何地方创建目录,cmd中cd 路径…...

代码随想录算法训练营第五六天| 99. 岛屿数量 100. 岛屿的最大面积
今日任务 99. 岛屿数量 深度搜搜 99. 岛屿数量 广度搜索 100. 岛屿的最大面积 99. 岛屿数量 题目链接: 99. 岛屿数量 import java.util.Scanner;public class Main {public static int[][] dir {{0, 1},{1, 0},{-1, 0},{0, -1}};public static void dfs(boolean…...

图解 微信开发者工具 小程序源码 调试、断点标记方法 , 微信小程序调试器,真机调试断点调试方法,小程序网络API请求调试方法 总结
在我们使用微信开发者工具进行微信小程序开发的时候,在这个微信开发者工具的代码编辑框里面我们是无法像使用vscode, idea等IDE工具时那样直接对代码打断点进行调试, 原因是小程序实际上他就是一个web浏览器应用的包装, 在其内部使用的还是类似chrome的…...

注释,换行,控制台输入输出,命名空间,省略return语句
注释 1.单行注释 // 2.多行注释 /*注释内容*/ 解释代码的作用;注释多余内容;注释不会影响代码执行 换行 \nstd::endl 控制台输入输出 输出123456 可一次性输出多个 std::cout<<"123456"//示例获取控制台输入内容,存储在…...

宠物空气净化器该怎么选?希喂,小米、安德迈这三款好用吗?
不得不说,虽然现在购物网站的活动不少,可力度都好弱啊!我想买宠物空气净化器很久了,觉得有点贵,一直没舍得入手。价格一直没变化,平台小活动根本没什么优惠,只能寄希望于双十一了,准…...

【Mybatis篇】Mybatis的注解开发
🧸安清h:个人主页 🎥个人专栏:【计算机网络】,【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 文章目录 🎯 Select注解 …...

NEC协议
NEC协议是一种红外线通信协议,广泛应用于家电遥控器和其他红外线设备之间的通信。以下是对NEC协议的详细解释和介绍: 一、开发背景与应用 NEC协议由日本电子公司NEC(日本电气公司)开发,因其简单、易于实现和广泛兼容…...

Meta 发布 Quest 3S 头显及 AR 眼镜原型:开启未来交互新视界
简介 在科技的浪潮中,Meta 始终站在创新的前沿,不断为我们带来令人惊叹的虚拟现实和增强现实体验。2024 年 10 月 6 日,让我们一同聚焦 Meta 最新发布的 Quest 3S 头显及 AR 眼镜原型(Orion),探索这两款产品…...

【CSS】水平垂直居中
给父盒子设置属性 flex display: flex;写在父元素上这就是定义了一个伸缩容器justify-content:center 设置主轴对齐方式为居中,默认是横轴。子元素居中。align-items:center 设置纵轴对齐方式为居中,默认是纵轴。子元素居中。 给…...

欧盟零毁林法案 EUDR
EUDR法案,即欧盟零毁林法案(EU Deforestation Regulation),是欧盟为了减少全球森林砍伐和退化,应对气候变化和生物多样性丧失而制定的一项重要法规。以下是对该法案的详细解读: 一、法案背景与目的 EUDR法…...

26.删除有序数组中的重复项
题目::26. 删除有序数组中的重复项 - 力扣(LeetCode) 思路:只要不和前面的数一样就可以移动指针,进行赋值 代码: class Solution { public:int removeDuplicates(vector<int>& nums) {int slow 0 ;for(int fast 1; fast < …...

JAVA实现公众号扫码登录和关注功能实战
前言 使用第三方插件 <dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>4.6.0</version> </dependency>准备APPID和appSecet 登录微信公众号后台,复制ap…...

初识Mysql/备份,基础指令
1,MySQL登录指令: mysql -h 127.0.0.1 -P3306 -u -p 其中,-h指明登录部署了mysql服务的主机 -P指明要访问的端口号, -u指明登录用户 -p输入密码 2,数据库基础 mysql:表示的是客户端 mysqld&…...

没想到吧!线稿上色居然可以这么简单
前言 在创意无限的数字艺术世界里,艺术创作中的线稿上色,向来是件既费时又需技巧的活儿,寻找一款既能激发灵感又能简化繁琐流程的工具,是每位艺术家心中的向往。 今天,为大家推荐一款革命性的线稿上色AI工具——千鹿…...

修改Docker的默认存储路径
docker默认存储路径:/var/lib/docker/ 执行 docker info 查看,得到以下信息 Docker Root Dir: /var/lib/docker/Debug Mode: falseRegistry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries: 1.修改docker配置 要修改默认…...

深入计算机语言之C++:C到C++的过度
🔑🔑博客主页:阿客不是客 🍓🍓系列专栏:从C语言到C语言的渐深学习 欢迎来到泊舟小课堂 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 一、什么是C C(c plus plusÿ…...

HR面试篇
一.面试中被问职业规划 HR感兴趣的不是你的职业规划,感兴趣的是你的职业规划和他们公司有没有关系。 或者说他们公司能不能去帮助你去实现你的职业规划。 切忌不要讲不合实际的,比如要在公司赚多少钱等等。 要根据公司的特点,找到切入点,只要讲得积极向上就可以。 二.…...

深度探索Kali Linux的精髓与实践应用
Kali Linux简介 Kali Linux作为全球网络安全领域的首选操作系统之一,其强大的功能性及广泛的适用范围令人瞩目。除了上述基础介绍外,让我们深入探究Kali Linux的几个关键特性及其在实际操作中的具体应用案例。 Kali工具集成:全面的安全工具…...

【在Linux世界中追寻伟大的One Piece】DNS与ICMP
目录 1 -> DNS(Domain Name System) 1.1 -> DNS背景 2 -> 域名简介 2.1 -> 域名解析过程 3 -> 使用dig工具分析DNS 4 -> ICMP协议 4.1 -> ICMP功能 4.2 -> ICMP报文格式 4.3 -> Ping命令 4.4 -> traceroute命令 1 -> DNS(Domain Na…...

信息安全工程师(41)VPN概述
前言 VPN,即Virtual Private Network(虚拟专用网络)的缩写,是一种通过公共网络(如互联网)创建私密连接的技术。 一、定义与工作原理 定义:VPN是依靠ISP(Internet Service Provider&…...

算法:双指针系列(一)
双指针系列 一、移动零(一)题目分析(二)代码展示二、复写零(一)题目分析(二)代码展示三、快乐数(一)题目分析(二)代码展示(…...

跟《经济学人》学英文:2024年09月28日这期 The curse of the Michelin star
The curse of the Michelin star Restaurants awarded the honour are more likely to close, research finds 原文: The twelve new restaurants added to the New York Michelin Guide this month, serving up cuisine ranging from “haute French” to “eco…...

Java Set 的介绍与实现原理
什么是 Set 在 Java 中,Set 是一种集合类型,它不允许重复的元素。Set 接口是 Java Collections Framework 的一部分,主要用于存储不重复的值。常见的实现类包括 HashSet、LinkedHashSet 和 TreeSet。 实现原理 1. HashSet HashSet 是最常…...

我谈均值平滑模板——给均值平滑模板上升理论高度
均值平滑(Mean Smoothing),也称为盒状滤波(Box Filter),通过计算一个像素及其周围像素的平均值来替换该像素的原始值,从而达到平滑图像的效果。 均值平滑通常使用一个模板(或称为卷…...