java知识框架

面试1

基础篇

  • 如何理解OOP面向对象编程?

对现有事物进行抽象,具有继承、封装、多态的特征。

继承:从已有的类也就是父类进行继承信息。
封装:对数据和数据操作的方法绑定起来,通过方法进行访问或者操作数据。
多态:让不同的子类对于同一消息做出不同的反应。比如父类的引用指向不同的子类,则会使用指向子类的方法。


  • 重写和重载的区别?

重写:就是overrider,实现在继承父类方法和实现接口的方法,访问修饰符不能降低,返回值 + 方法名 + 参数 必须一样。
重载:在同一个类中,方法名一样且参数必须不一样,修饰符 + 返回值 + 抛出异样可以任意。


  • 接口和抽象类区别?

抽象类:需要子类单继承,可以有构造器和成员变量,抽象方法不可以是private,除了不能进行实例化其余和普通类一样。
接口:需要类进行实现,接口只能是public(默认abstract),没有构造器和成员变量,只能声明常量(默认public static final)。


  • 浅拷贝和深拷贝区别?

拷贝就是对象有两种,基本类型和实例对象的引用。

浅拷贝:基本类型OK,拷贝实例对象就是返回对象的引用,实际还是同一个对象。
深拷贝:基本类型OK,拷贝实例对象时会进行对象内容的复制,非同一个对象。


  • sleep 和 wait 区别?

sleep:属于Thread中的方法,释放CPU不释放资源。比如sleep(1000)。
wait:属于Object中的方法,释放CPU和资源,使用wait()方法需要使用synchronized(否则抛出IllegalMonitorStateException)。比如wait(1000) 或者 搭配 notify()使用


  • 自动拆箱装箱?int和Integer区别?

由于基本类型不具有方法,有时候需要转化为包装类,拆箱装箱就是在两者之间进行转化。自动是因为javac编译器的语法糖,底层通过Integer.valueOf(99) 和 integerObj.intValue() 实现。

int 和 Integer 默认值分别为0 和 null,前者直接存储数据值,后者则是存储的引用地址。


  • == 和 equal 区别?

==:如果为基本类型直接比较值,如果为引用类型,比较地址。

equal:Object类中方法也是 == 进行比较地址。比较内容需要重写。


  • String为何使用final修饰?

主要是为了安全,final修饰表示字符串具有不可变性,标志线程安全。同时不可变性也提高了效率,如果创建相同的对象,则直接指向同一地址,无需创建新对象;由于不可变性并且hashcode也是不变的。


  • StringBuffer 和 StringBuilder 区别?

功能和方法完全等价,比如append,insert,delete等方法。StringBuffer中方法大都采用了synchronized 修饰,表示线程安全但是效率降低,因此可以多线程。StringBuilder 中没有采用,因此线程不安全但效率相对更高,适合单线程。


  • final、finally、finalize区别?

final:修饰类:表示不可继承、修饰方法:子类只能使用不可重写、修饰变量:给定初始值之后不再改变。
finally:try…catch…中finally表示最终执行的代码块,无论是否异常都要执行(除非JVM关闭),因此这里可以释放资源。
finalize:Object中的方法,垃圾收集在销毁对象时会执行这个方法,通过重写可以进行整理系统资源和其他清理工作


  • Object中有哪些方法?

有部分方法修饰符final、native,请注意。

protected Object clone():

String toString()

boolean equals(Object obj) 、

int hashCode()

void wait()

void notify()

void notifyAll()

Class<? extendsObject> getClass()

protected void finalize()


  • 集合体系?

Iterable接口,演化出Collection接口,从而演化出Set接口和List接口,Set接口实现类中有HashSet(其子类为LinkedHashSet),TreeSet;List接口实现类有ArrayList 和 LinkedList 。
Map接口实现类有HashMap(其子类为LinkedHashMap),TreeMap;


  • ArrayList 和 LinkedList 区别?

ArrayList:底层为动态数组,随机访问get和set 效率较高。
LinkedList :底层为链表,增删add和remove 效率较高。


  • HashMap?

底层的数据结构时 数组 + 链表 + 红黑树。初始时数组为16,通过计算元素的hash值放入相应的位置,冲突则转为链表,当元素到达默认负载因子0.75也就是元素为12的时候,数组开始扩容为原来的2倍,继续增加元素扩容至64时,当其中一个位置也就是桶,当这个桶里面的元素达到8个时转化为红黑树,如果再减小到6,再次转为链表。


  • HashMap 和 HashTable 和 ConcurrentHashMap 区别?

HashMap:线程不安全,允许一个null键和多个null值,
HashTable:使用Synchronized所以线程安全。K和V均不许出现null。基本所有方法都是用synchronized。初始为11,扩容则为2n + 1。
ConcurrentHashMap:线程安全。K和V均不许出现null,ConcurrentHashMap性能由于锁的粒度较小,所以比HashTable效率高。java8之前使用Segment从而实现一定的并行性。java8之后采用CAS(Compare-And-Swap)和细粒度锁

CAS:使用大部分是Navtive方法高效。比较内存中的值和预期值是否相等,相等则更新值。否则重新获取内存值设置为预期值,重试直至成功
细粒度锁:对一个桶进行加锁,极大提高并行性


  • 线程创建的方式几种?

一般来说就是 3种(本质都是实现Runnable接口) + 线程池

继承Thread类:重写run方法。myThread.start()
实现Runnable接口:重写run方法。Thread(new myRunnable).start()
实现Callable<>接口:重写run方法。 FutureTask(myCallable).run();

线程池:实例化ThreadPoolExecutor(…),执行execute(myThread),然后shutdown关闭线程池。也可以使用并发包中Executors直接调用所需要的线程池。


  • 线程的生命周期(状态转化)?

NEW:实例化产生一个新的对象。调用start进入RUNNABLE
RUNNABLE:当获取CPU则为RUNNING,实际取决于CPU的调度。yield方法会让出CPU,RUNNING会转为RUNNABLE
BLOCKED:线程要获取的资源已经被其他线程加锁了;获取资源之后,转为RUNNABLE
WAITING:无限期等待wait()、join()、park(),直至被唤醒进入RUNNABLE
TIMED_WAITING:限时等待sleep(1000)、wait(1000)、join(1000),到达时间或者被唤醒进入RUNNABLE
TERMINATED:线程结束。


  • java中有几种类型的流?

主要分为字节流和字符流

字节流:FILE\Buffered + InputStream\OutputStream。FILE可以表示图片等,BufferedInputStream 是InputStream的间接子类(孙子)
字符流:FILE\Buffered + Reader\Writer。FILE用于字符类文件,BufferedReader特有方法readline()。BufferedWriter特有方法newLine(),write(str)。
转化流:继承字符流。InputStreamReader 、OutputStreamWriter字节流转为字符流,


  • 常见的RuntimeException,举例

NullPointerException:使用未初始化或者不存在的对象。
IndexOutOfBoundsException:数组越界
ClassNotFoundException:类的路径或者名称错误
ClassCastException:类型转化异常
NumberFormatException:字符串转为数字异常,包含非数字的字符
IllegalArgumentException:方法中参数不符。


  • 反射机制?

反射机制就是java在运行时拥有自观的能力,通过这种能力可以了解自身状态,进行下一步操作。Class、Constructor、Method、Field四种类可以粗略的看到类的组成部分。


  • java序列化?

序列化是对象转为流的机制,内容就是toString()返回的,进行持久化存储或传输。只需要Serializable接口,仅仅标注此对象可被序列化。但是transient 和 static 不会被持久化,比如transient 修饰密码。

通过一个FileOutputStream构造一个ObjectOutputStream, writeObject(Object obj)就持久化对象。


  • 常见的HTTP状态码?

1xx表示信息性、2xx表示成功、3xx表示重定向、4xx表示客户端错误、5xx表示服务器错误。

200表示OK成功,301表示Moved Permanently,302Found临时重定向,400表示Bad Request客户端请求语法错误,401表示Unauthorized ,403表示Forbidden ,500表示Internal Server Error,503表示Server Unavailable


  • GET 和 POST 区别?

两者都是底层都是TCP/IP。

GET:通过URL请求,请求的信息在url中,比如login.action?name=lisi&password=123456,明文不安全。请求获取数据,浏览器发送header和data,服务器返回200并返回数据。
POST:通过FORM表单请求,提交的数据在HTTP包的包体中。发送数据到后台,浏览器先发送header,收到服务器的100状态码(Continue),然后在发送data,最后服务器响应200并返回数据。

header:包括元数据,比如Host、Content-Type、Content-Lenghth、User-Agent等。
data:包括具体的参数信息等。


  • Cookie 和 Session 区别?

Cookie:是Web服务器发送给Client端的信息,浏览器会在本地存储Cookie。以后再请求此服务器则会发送相应的Cookie。Cookie只存储字符串
Session:存储在Web服务器的信息,session对象存储用户会话所需的属性和配置信息,用户在Web跳转时不会丢失此信息。Session可以存储任何对象。

一般来说Cookie中存储SessionID,发送到Web服务器后,直接根据SessionID使用之前Session,依然显示登陆和偏好之类的。

高级篇

  • JVM内存分区,每个区分的作用?

字节码class文件加载到Class loader类装载器系统(双亲委派机制从bootstrap-extension-application)→ 链接 → 初始化。然后和运行时数据区进行交互。运行时数据区有五部分,运行时数据区和本地方法接口和执行引擎三者相互交互,本地方法接口是由本地方法库实现的。

加载:

链接:

  1. 验证:字节码文件格式,元数据验证,字节码验证
  2. 准备:给静态变量分配空间并初始化默认值,不执行静态代码块或者静态字段的赋值
  3. 解析:符号引用(类名、方法名、字段名等)转化为直接引用的过程

运行时数据区的五部分:栈 + PC 线程私有也就是安全的;堆 + metaspace 线程共享,且是JVM调优的主要地区。

  1. java栈:每次方法调用就会创建一个栈帧,执行结束后弹出栈帧。栈帧主要由四部分:

    1. 局部变量表:基本数据类型,引用类型,returnAddress 类型(保存PC指向地址)
    2. 操作数栈:用于计算操作。
    3. 动态链接:保存指向运行时元空间的方法和字段引用;支持方法调用中的符号引用到直接应用
    4. 方法返回地址:返回到调用者的地址
  2. 本地方法栈:和java栈类似,只不过是navtive方法

  3. PC:指向下一条指令

  4. 堆:存储对象的实际内容

    1. 新生代:新的实例化对象在eden,s0和s1
    2. 老年代:新生代15gc后,则进入老年代。老年代中的gc速度赶不上对象生产的速度就会OOM,
  5. 方法区:也称永久代,Java8之后称为元空间metaspace

    1. 类的元数据:类的全名、类的修饰符、父类和接口的引用、方法、静态变量
    2. 常量池:字面量常量、符号引用(其他类、方法、字段的引用,运行时符号引用被解析成直接引用)
    3. JIT编译后的机器码:比如热点代码,直接执行这些机器码提高效率

执行引擎:作用就是把字节码编译\解释为机器码,操作系统才能执行。

  1. 解释器:按行解释字节码并执行
  2. 即时编译器JIT:中间代码生成器、代码优化器、目标代码生成器。分析器
  3. GC:进行垃圾回收

  • 类加载器?

四种:

  1. Bootstrap:加载java核心类库,无法被java程序直接引用
  2. Extension:加载java的扩展库。
  3. Application(System):根据java类的路径加载java类,一般来说java的应用类都是由他来完成。ClassLoader.getSystemClassLoader()获取
  4. 自定义:继承java.lang.ClassLoader类的方式实现。

java的加载器是按需加载,什么时候用到(类或者接口,其中的方法和字段,子类),什么时候加载。


  • JVM中GC策略?

Minor GC:当Eden没有空间,就会此策略。会将Eden和From Survivor转移到To Survivor。且三者默认比例为8:1:1。
Major GC (Full GC):堆整个堆进行回收,JVM此时会暂停所有线程。


  • java中垃圾收集器的算法?

复制算法:用于新生代中
标记-清除 和 标记-整理:混合用于老年代,清除会产生碎片,整理不会有碎片。


  • 如何判断一个对象是否存活(GC判定方法)?GC roots?

可达性算法:通过GC Roots作为起点,然后向下一直搜索,走过的路径为Reference Chain,当一个对象无法通过Chain链接到GC Roots则认为对象不可用。
引用计数法:不用,容易出现循环而无法回收

GC roots:活跃的java线程、栈的局部变量、类的静态字段、JNI的引用、JVM的内部对象…


  • StackOverflowError 和 OutOfMemoryError 什么情况?如何排查?

StackOverflowError:调用方法过多,无线递归,海量的局部变量,Navtive方法中比如 java.net.SocketInputStream.read0 要求分配空间过多。
OutOfMemoryError:死循环创建对象,从数据库中取出过度的数据,对象引用为清空导致JVM无法回收,设置内存太小。

排查:通过jvisualvm进行内存快照分析


  • 线程池有哪些? 线程池的优点?

Executors.newSingleThreadExecutor():单个线程按顺序执行,此线程异常结束,则会有新的线程替代。
Executors.newFixedThreadPool(5):指定线程的个数
Executors.newCachedThreadPool():创建线程数量没有限制(Interger. MAX_VALUE),虽然可以灵活的增加线程,过多的线程造成系统崩溃
Executors.newScheduledThreadPool(5):指定线程的个数,可以周期性执行任务,比如延迟2秒执行。

上面返回的是ExecutorService接口,底层还是通过ThreadPoolExecutor类进行操作。

优点:

  1. 降低资源消耗,提高速度:不需要在创建新的线程,直接使用
  2. 提高线程的管理型:线程是稀缺资源,过多线程会造成系统崩溃,线程池可以对线程进行统一分配,调优和监控

  • 线程池的状态?

Running:创建或者使用execute()进入此状态
Shutdown:调用shutdown(),不再接受新的任务,但线程池执行完队列。
Stop:调用shutdownNow(),立即停止执行的任务。
Tidying:由Shutdown和Stop转来,不做任何处理。
Terminated:由Tidying转来,所有线程都终止


  • 线程池工作原理?
  1. 线程池实例化后,有任务过来才开始创建线程;也可以预先创建线程prestartCoreThread() 或 prestartAllCoreThreads()
  2. 调用execute()执行任务时,如果工作核心线程小于设定的,则创建核心线程并执行
  3. 如果核心线程已经最大,则进入等待队列
  4. 如果队列已满,但是maximumPoolSize未满,则开启新线程执行任务。如果maximumPoolSize满了抛出RejectedExecutionException

  • ThreadPoolExecutor对象中参数?
public ThreadPoolExecutor(int corePoolSize,		int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) 

阻塞队列BlockingQueue接口参数:

  1. ArrayBlockingQueue<>(5):数组,有界
  2. LinkedBlockingQueue<>():链表,默认无界,可以给参数设定为有界。
  3. SynchronousQueue<>():无缓冲队列,来一个任务必须有线程执行,没有空闲线程,则任务堵塞

线程工厂ThreadFactory:

  1. 直接实现ThreadFactory接口,创建Thread
  2. Executors.defaultThreadFactory() 获取线程工厂

拒绝策略RejectedExecutionHandler:当队列满,且线程数量满,提交新的任务会拒绝

  1. AbortPolicy:默认策略,直接抛出RejectedExecutionExcepiton
  2. CallRunsPolicy:直接有提交任务的线程执行此任务。
  3. DiscardPolicy:直接丢弃
  4. DiscardOldestPolicy:丢弃最旧的任务,然后提交当前任务

如果CPU密集型,说明一直需要CPU执行任务,所以 线程数 = CPU个数。
如果是IO密集型,则可以多设置点线程,比如 线程数 = 2*CPU个数。
线程池最佳线程个数 = (等待时间 + CPU执行时间) / CPU执行时间 * CPU个数


  • 常见线程安全的并发容器?

CopyOnWriteArrayList、CopyOnWriteArraySet:通过复制保证线程安全。
ConcurrentHashMap:上面说过


  • Atomic原子类?

java中的原子类存放在JUC下的atomic下。

基本类型:AtomicInteger、AtomicLong、AtomicBoolean
数组类型:AtomicIntegerArray、AtomicLongArray
引用类型:AtomicReference、AtomicMarkableReference

AtomicInteger 通过使用CAS + volatile + native实现,避免synchronized 高开销,提升了效率


  • synchronized 和 Lock 区别?
synchronizedReentrantLock
关键字,JVM层面的锁(更底层C++实现)类,API层面的锁
自动加锁、自动释放手动上锁,手动释放
非公平锁公平锁、非公平锁
不可中断可中断,tryLock(long timeout,timeUnit unit); lockInterruptibly()
锁的对象,锁信息保存在对象中int类型state来标识锁的状态
底层有锁升级过程:偏向锁 、轻量级锁、重量级锁无升级

  • synchronized 和 volatile 区别?

volatile:保证变量的可见性,但线程不安全。不阻塞。仅仅修饰变量。且禁止指令重排,JVM优化没了
synchronized :保证变量的可见性和线程安全。会阻塞。可以修饰变量、方法、块。

synchronized 方法:无static则一个实例一把锁,有static则所有实例一把锁。


  • 死锁?java中如何查看死锁?

死锁的四个必要条件:互斥、请求与保持、不可剥夺、循环等待。

死锁检测:确保第一时间发现并解决。图算法查看是否死锁
解决死锁,破坏其中一个条件即可:注意加锁顺序,加锁设上时间。
死锁预防:银行家算法

jsp:可以产看对应进行,比如死锁进程为pid22080,
jstack 22080:可以查看信息


面试2

  • 为什么不建议使用Executors.newFixedThreadPool创建线程池

通过查看源码,阻塞队列默认为LinkedBlockingQueue,由于没有设置多少个任务,默认会有Integer.MAX_VALUE。容易造成内存溢出。


  • ThreadLocal?应用场景

每一个线程拥有一个ThreadLocalMap,且Entry中key为ThreadLocal,value则为ThreadLocal存储的值。通过ThreadLocal.set(value)可以在map中存储一个对应的entry。

应用场景:A、B、C如果同时使用一个信息,则可以使用ThreadLocal共享变量。存储线程不安全,比如SimpleDataFormat

简介

Sun公司发明Java,后面Oracle收购Sun。所以Java在Oracle官网。

Java分为JavaSE、JavaEE、JavaME。现在javaME被Android占领。

JDK包括JRE,JRE包括JVM

Java的语言类型:java准确来说属于混合型语言,但更偏向于解释型。

编译:java存在JIT和AOT,JIT是以字节码程序存在,并且将可将热点代码直接编译成机器码(本地代码),AOT可在安装时把代码编译成机器码。并且安装时一般不带有源码*.java,安装好是以字节码或者机器码存在的。

解释:java运行时需编译成class文件,JVM在解释class文件。

image-20231225230941137

环境配置:

  • JAVA_HOME
  • path:%JAVA_HOME%\bin,%JAVA_HOME%\jre\bin

jdk文件夹:

  • bin、include、lib
  • src.zip\java存放Java核心库源代码
  • jre\lib\rt.jar是运行时的核心库相应的字节码,同上。

测试:java -version

java

project -> module -> package -> class

心代码库rt.jar:

  • text、beans、security
  • rmi:
  • nio:new IO非阻塞
  • applet,Apple是采用Java编程语言编写的小应用程序,该程序可以包含在 HTML(标准通用标记语言的一个应用)页。

javaAPI

常用命令

javac HelloWorld.java	# 生成HelloWorld.class 字节码
java HelloWorld			# 运行字节码# @param,return,throws,author,version,since
javadoc HelloWorld.class jar cf Hello.jar HelloWorld.class 	# 生成jarjps		# 产看java运行的进程状态
jstatck pid		# 产看某进行的栈信息jconsole	# 打开 Java监视和管理控制台

javadoc -d doc -encoding utf-8 MyClass.java 命令产生文档

package org.example;/*** 这里是类的 Javadoc 注释* 可以简要描述类的作用和功能* * @author 张三* @version 1.0* @since 2025-01-13*/
public class MyClass {/*** 这是方法的 Javadoc 注释* * @param name 传入的姓名* @return 返回问候语*/public String greet(String name) {return "Hello, " + name;}
}

static方法

static方法:类本身的方法。有无实例均可使用。

// Demo1:
class Parent {// 此方法,可继承使用 或 隐藏,不可重写;public static  void say(){System.out.println("Parent hello");}
}
class Child extends Parent{// 这种是“隐藏hiding”,而非“重写override”public static void say(){System.out.println("Child hello");}
}
// 每个类调用本身(非实例)的方法
Child.say();	// 如果子类没有方法say(),则调用父类static方法。
Parent.say();	
// parent.say() 编译错误// 拓展Demo2: 变量隐藏:子类和父类同名变量,覆盖父类的此变量
class Parent {String name = "Parent";void printName() {System.out.println("Parent name: " + name);}
}class Child extends Parent {String name = "Child"; // 变量隐藏void printName() {System.out.println("Child name: " + name);}void printBothNames() {System.out.println("Child name: " + name);System.out.println("Parent name: " + super.name);}
}public class Main {public static void main(String[] args) {// 父类引用(即使指向子类对象)访问变量时,使用的是父类的变量。Parent parentRef = new Child();System.out.println("ParentRef.name: " + parentRef.name); // 输出: ParentparentRef.printName();       // 输出: Child name: ChildparentRef.name;		// 注意区分:值为: ParentparentRef.printBothNames();	//  输出: Child  Parent}
}
// 变量的绑定是静态绑定,编译期间就确定了
// 方法是动态绑定(运行时绑定)

常用的静态方法,也就是工具类

# util中
Arrays.sort(numsarry);
Arrays.toString(numsarry);

final

final:修饰类 、方法、变量

class Parent {// final修饰方法:子类直接用,无法重写public final void display() {System.out.println("Parent's final method");}   
}// final修饰的类不可继承,比如String、Integer、UUID

protected方法

类中protected方法:比如自己包内的Demo类,是无法使用的

// 不同包,直接通过父类调用protected方法,编译错误// 如果想要调用,则需要写一个子类继承这个类,然后子类通过改方法为public型即可

tip:面试clone()为啥需要重写(提示:protected)?

构造器

  • 如果父类有无参构造器,子类默认调用
// Demo1: 无参构造器,
class Parent {public Parent() {System.out.println("Parent constructor");}
}class Child extends Parent {// 默认构造器会隐式调用 super()
}public class Main {public static void main(String[] args) {new Child(); // 输出: Parent constructor}
}// Demo2: 有参数构造器
class Parent {public Parent(String name) {System.out.println("Parent constructor: " + name);}
}class Child extends Parent {// 必须显式调用父类构造器。否则编译报错public Child(String name) {super(name);}
}public class Main {public static void main(String[] args) {new Child("Child"); // 输出: Parent constructor: Child}
}

代码块执行顺序:静态代码块 > 初始化代码块 > 构造器

class MyClass {// 静态代码块,类加载时执行,只执行一次。static {say("static");}// 实例初始化代码块,每次创建对象时执行,优先于构造器。{say("default");}
}

接口

interface MyInterface {// 只有一个抽象方法,为函数式接口,可以使用lambda/*MyInterface myInterface2 = () -> System.out.println("Ha...");myInterface2.say();*/void say();// 只能这样用 MyInterface.staticMethod(); 且无法重写static void staticMethod() {System.out.println("Static method in interface");}// 必须加上default,仅供实例使用。default void defaultMethod() {System.out.println("Default method in interface");}
}class MyClass implements MyInterface {// 可以选择实现接口的普通方法和default方法,@Overridepublic void say() {}
}public class Main {public static void main(String[] args) {// 创建接口的实现类实例MyInterface obj = new MyClass();        // obj.staticMethod(); // 错误,编译不通过// 调用接口的默认方法obj.defaultMethod(); // 正确调用}
}

lambda表达式

函数式接口(Functional Interface)是仅 一个抽象方法 的接口,函数式接口可以有多个 默认方法静态方法

常用:

  • Runnablerun(),适用于没有参数和返回值的任务。
  • Consumer<T>accept(T t),用于处理类型为 T 的对象(不返回值)。
  • Supplier<T>get(),用于提供类型为 T 的对象。
  • Function<T, R>apply(T t),用于将一个对象转换为另一个对象。
  • Comparator<T>compare(T o1, T o2),用于定义对象的比较逻辑。

Demo:

// Demo1: 线程
new Thread(() -> System.out.println("Hello World")).start();// Demo2: Consumer<T>
Consumer<String> stringConsumer = s -> System.out.println("Consumer: " + s);
stringConsumer.accept("Hello World");// Demo3: Supplier<T>
Supplier<Integer> integerSupplier =() -> Integer.valueOf(123);
System.out.println(integerSupplier.get());// Demo4: Function<T, R>。T:type,R:result。亦可(String s) -> s.length()
Function<String, Integer>  stringIntegerFunction = s -> s.length();	
System.out.println(stringIntegerFunction.apply("hello"));// Demo5: Comparator<T>
String[] names = {"Alice", "Tom", "Bob"};
// 等效Comparator<String> stringComparator = String::compareTo;
Comparator<String> stringComparator = (s1, s2) -> s1.compareTo(s2);
Arrays.sort(names, stringComparator);	// 列表:Collections.sort(names, ...);
System.out.println(Arrays.toString(names));// forEach中lambda
list.forEach(item -> System.out.println("===" + item));
map.entrySet().forEach((entry) -> System.out.println(entry.getKey() + entry.getValue()));

注解

常用注解

  • @Override 实现父类或接口的方法
  • @Deprecated 标记过时的 类、方法、字段
  • @SuppressWarnings 抑制编译器的警告信息,尽量少用。比如@SuppressWarnings(“unchecked”)
  • @FunctionalInterface 函数式接口
  • @Retention 保留,参数可选SOURCE,CLASS,RUNTIME
  • @Target 用于标注注解的注解,表示可以使用的地方T,参数有TYPE、FIELD、METHOD…
  • 自定义注解
// Demo1: 自定义注解
@Target(ElementType.TYPE)	
@interface MyAnnotation {String value() default "Defalut";
}@MyAnnotation(value = "2")
public class Demo {}

常用类

java.langObject、Throwable、Exception、ErrorString\StringBuffer\StringBuilderBoolean、Character、Byte\Short\Integer\Long\Math、Float\Double	Class\ClassLoader、Runnable\Thread\ThreadDeathSystem\Runtimejava.utilDate\Calendar\GregorianCalendar*List\*Set\*Map\VectorRandomjava.io*InputStream\*OutputStream\*Write\*Read、Filejava.netURL*/Socket*/Cookie*

java.lang

基本数据类型

long num1 = 1L;		// 1默认类型为int
float f1 = 1.0f;	// 1.0默认类型为double
double d1 = 1.0;		// 1D表示1.0,
int oct = 0123;     //八进制
int hex = 0xaa		// 16进制// 常见范围
Integer.SIZE;
Integer.MIN_VALUE;
Integer.MAX_VALUE;/*  常见默认值:char '\u0000'3.14E3 是3140,3.14E-3 是0.00314
*/// 常见的方法
int a = Integer.parseInt(str);
dobule b = Double.parseDouble(str);// String
String str = null;
System.out.println(str);       // 输出 null
System.out.println(str.length()); 	// NullPointerException// Integer.valueOf()源码。包装类a=1 b=1指向同一地址
public static Integer valueOf(int i) {assert IntegerCache.high >= 127;if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}int a=10;
int b=20;
System.out.println(""+a+b);         //1020
System.out.println(a+b+"");         //30

Object

// Demo1: 
// 有方法 hashCode(), equals(),toString()
// 使用 toString 方法。输出:对象包名@hash值
// 等效System.out.println(obj1);在sout才会自动调用toString()// Demo2: 
// clone(), 在Object中修饰符是 protected,需要重写。
public class MyClass implements Cloneable {	// 接口Cloneable,象征性的表示可以克隆private int value;public MyClass(int value) {this.value = value;}//显式调用父类的 clone 方法,这样子类Demo才可以使用父类的clone();@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();		// 这里是浅拷贝,同一个数据的不同引用// 深拷贝,复制数组。/*                Demo cloned = (Demo) super.clone(); cloned.values = Arrays.copyOf(this.values, this.values.length);return cloned;*/}@Overridepublic String toString() {return "value: " + value;}
}public static void main(String[] args) {try {MyClass original = new MyClass(42);MyClass copy = (MyClass) original.clone();System.out.println(original);System.out.println(copy);} catch (CloneNotSupportedException e) {e.printStackTrace();}
}

Throwable

public class ThrowableExample {public static void main(String[] args) {try {throw new Throwable("This is a Throwable example");} catch (Throwable t) {System.out.println("Caught Throwable: " + t.getMessage());t.printStackTrace();// 加下面代码,则直接结束方法,抛出异常,下面sout不会被打印,// throw new RuntimeException(t);}System.out.println("=====");}
}

Exception

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;public class ExceptionExample {public static void main(String[] args) {try {// 试图读取一个不存在的文件File file = new File("nonexistent_file.txt");Scanner scanner = new Scanner(file);} catch (FileNotFoundException e) {System.out.println("Exception caught: " + e.getMessage());}}
}

NullPointerException

public class NullPointerExample {public static void main(String[] args) {String str = null; // str 未初始化System.out.println(str.length()); // 尝试调用方法,抛出 NullPointerException        // 解决思路:if判断是否null, 或者捕获异常        String[] strings = new String[5];System.out.println(strings[0].length());	// 同样,抛出 NullPointerException    }
}

IllegalArgumentException

public class Demo {public static void main(String[] args) {printAge(-1);}public static void printAge(int age) throws IllegalArgumentException{if (age < 0){throw new IllegalArgumentException("age Exception :" + age);}System.out.println("age: " + age);}
}

Error

// 无限递归,Error也可用catch捕捉

String、StringBuffer、StringBuilder

特性StringStringBufferStringBuilder
是否可变不可变可变可变
线程安全性是(不可变实现线程安全)是(同步机制synchronized实现线程安全)否(不支持同步)
性能最慢较快(线程安全开销)最快
使用场景少量字符串修改多线程环境频繁修改单线程环境频繁修改
public class StringExample {public static void main(String[] args) {String s1 = "Hello";String s2 = s1 + " World"; // 生成新对象// 方法 append() insert() delete() replace() reverse()StringBuffer sb = new StringBuffer("Hello");System.out.println("StringBuffer result: " + sb.toString()); // StringBilder同上}
}

特性String s = new String("123")String s = "123"
创建对象个数每次创建新对象常量池中存在,直接引用
存储位置堆内存字符串常量池
是否共享对象不共享共享(如果内容相同),推荐使用

String类重写了equals,源码中是比较内容

基本数据类型和其包装类

public class BooleanExample {public static void main(String[] args) {Boolean isJavaFun = true;	// 基本类型Boolean isFishTasty = Boolean.valueOf("false");		// 包装类char c = 'A';Character ch = Character.valueOf(c);// 判断字符类型System.out.println(Character.isLetter(ch)); // trueSystem.out.println(Character.isDigit(ch)); // falseSystem.out.println(Character.toLowerCase(ch)); // abyte b = 10;Byte byteObj = Byte.valueOf(b);System.out.println("Byte value: " + byteObj); // 10System.out.println("Max Byte: " + Byte.MAX_VALUE); // 127System.out.println("Min Byte: " + Byte.MIN_VALUE); // -128short s = 1000;Short shortObj = Short.valueOf(s);System.out.println("Short value: " + shortObj); // 1000System.out.println("Max Short: " + Short.MAX_VALUE); // 32767System.out.println("Min Short: " + Short.MIN_VALUE); // -32768    int num = 12345;Integer intObj = Integer.valueOf(num);System.out.println("Integer value: " + intObj); // 12345System.out.println("Binary: " + Integer.toBinaryString(num)); // 11000000111001System.out.println("Max Integer: " + Integer.MAX_VALUE); // 2147483647System.out.println("Min Integer: " + Integer.MIN_VALUE); // -2147483648long l = 123456789L;Long longObj = Long.valueOf(l);System.out.println("Long value: " + longObj); // 123456789System.out.println("Hexadecimal: " + Long.toHexString(l)); // 75bcd15System.out.println("Max Long: " + Long.MAX_VALUE); // 9223372036854775807System.out.println("Min Long: " + Long.MIN_VALUE); // -9223372036854775808System.out.println("Absolute value: " + Math.abs(-5)); // 5System.out.println("Square root: " + Math.sqrt(16)); // 4.0System.out.println("Power: " + Math.pow(2, 3)); // 8.0System.out.println("Random number: " + Math.random()); // 0.0 to 1.0System.out.println("Max: " + Math.max(10, 20)); // 20float f = 3.14f;Float floatObj = Float.valueOf(f);System.out.println("Float value: " + floatObj); // 3.14System.out.println("Max Float: " + Float.MAX_VALUE); // 3.4028235E38System.out.println("Min Float: " + Float.MIN_VALUE); // 1.4E-45double d = 3.14159265359;Double doubleObj = Double.valueOf(d);System.out.println("Double value: " + doubleObj); // 3.14159265359System.out.println("Max Double: " + Double.MAX_VALUE); // 1.7976931348623157E308System.out.println("Min Double: " + Double.MIN_VALUE); // 4.9E-324}
}

tip:包装类中很多static方法可以直接调用,Integet,、String、Character、Arrays,等

整数

public class IntegerExample {public static void main(String[] args) {int num = 12345; // 基本数据类型Integer intObj = Integer.valueOf(num); // 包装类对象// 比较两者System.out.println("num: " + num); // 输出 12345System.out.println("intObj: " + intObj); // 输出 12345// 使用包装类的方法System.out.println("Binary of intObj: " + Integer.toBinaryString(intObj)); // 输出 11000000111001// 判断是否同一个对象Integer a = Integer.valueOf(100); // 在 -128 ~ 127 范围,返回缓存对象Integer b = Integer.valueOf(100);System.out.println(a == b); // true(引用相等,因为使用了缓存)Integer c = Integer.valueOf(200); // 超出缓存范围Integer d = Integer.valueOf(200);System.out.println(c == d); // false(引用不相等,创建了新的对象)}
}

Runnable

class MyTask implements Runnable {@Overridepublic void run() {System.out.println("Task is running: " + Thread.currentThread().getName());}
}public class RunnableExample {public static void main(String[] args) {MyTask task = new MyTask();Thread thread = new Thread(task); // 将 Runnable 对象传递给 Threadthread.start(); // 启动线程。如果使用thread.run();就是普通方法}
}

Thread

class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread is running: " + getName());}
}public class ThreadExample {public static void main(String[] args) {MyThread thread = new MyThread();thread.start(); // 启动线程thread.join(); // 等待此线程执行结束,再向下执行。	}
}

Callable<>

class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {System.out.println("hello world");return "hello";}
}FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
new Thread(futureTask).start();
System.out.println(futureTask.get());

线程中断

public class Test1 implements Runnable{volatile boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new Test1());thread.start();Thread.sleep(1000);thread.interrupt();}@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()){System.out.println("thread is executing");}System.out.println("thread is interrupted");}
}

ThreadDeath

public class ThreadDeathExample {public static void main(String[] args) {Thread thread = new Thread(() -> {try {while (true) {System.out.println("Running...");Thread.sleep(500);}} catch (ThreadDeath td) {System.out.println("ThreadDeath caught! Cleaning up resources...");throw td; // 重新抛出以终止线程} catch (InterruptedException e) {System.out.println("Interrupted!");}});thread.start();try {Thread.sleep(2000); // 主线程等待 2 秒} catch (InterruptedException e) {e.printStackTrace();}thread.stop(); // 强制终止线程,不推荐使用}
}

ClassLoader

public class ClassLoaderExample {public static void main(String[] args) {// 获取 ClassLoaderClassLoader classLoader = ClassLoaderExample.class.getClassLoader();System.out.println("应用类加载器: " + classLoader);ClassLoader parent = classLoader.getParent();System.out.println("扩展类加载器: " + parent);ClassLoader bootstrap = parent.getParent();System.out.println("引导类加载器: " + bootstrap); // 通常为 null,因为由本地代码实现/*	$ 表示子类应用类加载器: sun.misc.Launcher$AppClassLoader@18b4aac2扩展类加载器: sun.misc.Launcher$ExtClassLoader@74a14482引导类加载器: null*/}
}

Class

此类是 Java 反射机制的核心部分

public class ClassExample {public static void main(String[] args) throws Exception {// 获取 Class 对象的三种方式Class<?> cls1 = Class.forName("java.lang.String"); // 通过类名Class<?> cls2 = String.class; // 通过 .classClass<?> cls3 = "hello".getClass(); // 通过对象实例// 比较三个 Class 对象System.out.println(cls1 == cls2); // trueSystem.out.println(cls2 == cls3); // true// 获取类的信息System.out.println("类名: " + cls1.getName());System.out.println("类名: " + cls1.getSimpleName());System.out.println("包名: " + cls1.getPackageName());// 通过反射创建实例Object obj = cls1.getConstructor(String.class).newInstance("Dynamic String");System.out.println("创建的实例: " + obj);}
}

既然提到了Class,就说说反射。

反射

  • 优势:灵活(可以动态访问运行时的类和其方法),许多框架就使用反射技术实现自动化配置和依赖注入。
  • 缺点:性能开销(由于动态访问),不安全(可以访问private属性)
class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public void greet() {System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");}public void greet(String content) {System.out.println("Hello " + content);System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");}
}public class ReflectionExample {public static void main(String[] args) throws Exception {// 获取 Person 类的 Class 对象Class<?> clazz = Class.forName("com.adair.gpt.Person");// 获取类的构造方法Constructor<?> constructor = clazz.getConstructor(String.class, int.class);Person bob = (Person)constructor.newInstance("Bob", 18);// 获取所有字段Field[] fields = clazz.getDeclaredFields();// 获取name字段Field name = clazz.getDeclaredField("name");name.setAccessible(true);   // 设置为可接近,如果类中不是private,则不需要设置System.out.println(name.get(bob));name.set(bob, "Alice");System.out.println(name.get(bob));// 获取所有方法Method[] methods = clazz.getDeclaredMethods();// 获取特定的方法Method greet = clazz.getMethod("greet");greet.invoke(bob);Method greet2 = clazz.getMethod("greet", String.class);greet2.invoke(bob, "World");}
}

System:

// 获取系统时间。可以用于测试程序的时间。endTime - startTime
long currentTime = System.currentTimeMillis();
// 获取系统属性
String javaLibrary = System.getProperty("java.library.path");
// 获取环境变量
String path = System.getenv("Path");
System.getenv("windir");int[] source = {1, 2, 3, 4, 5};
int[] destination = new int[5];
// 方便	int[] ints = Arrays.copyOf(source, source.length);
System.arraycopy(source, 0, destination, 0, source.length);// 调用垃圾回收 和 退出程序
System.gc();
System.exit(0);
package com.gpt;import java.io.IOException;public class RuntimeExample {public static void main(String[] args) {// 单例模式Runtime runtime = Runtime.getRuntime();// 获取 JVM 内存信息。 总内存(可变)即开始运行的初始堆的大小。总内存固定。// 如果程序需要更多内存,JVM 总内存会自动扩展内存,直到达到最大内存的限制。System.out.println("JVM 总内存:" + runtime.totalMemory());System.out.println("JVM 可用内存:" + runtime.freeMemory());System.out.println("JVM 最大内存:" + runtime.maxMemory());// OutOfMemoryError 即超过最大内存/*打开VMoptions 修改参数,可以修改JVM内存-Xms512m   # 设置初始堆内存为 512MB-Xmx2g     # 设置最大堆内存为 2GB* */// 垃圾回收runtime.gc();// 执行外部命令try {Process process = runtime.exec("notepad"); // 在 Windows 上打开记事本Process process3 = runtime.exec("calc"); // 在 Windows 上计算器} catch (IOException e) {e.printStackTrace();}}
}

java.util

Date\Calendar\GregorianCalendar

public class Demo2 {public static void main(String[] args) {// 过时的,尽量不用Date date = new Date();System.out.println(date);// Calendar.getInstance();创建GregorianCalendar对象Calendar instance = Calendar.getInstance();// 输出很多属性, 远超DateSystem.out.println(instance);System.out.println(instance.get(Calendar.YEAR));System.out.println(instance.get(Calendar.MONTH) + 1);   // 月份从0开始instance.set(2024, Calendar.JANUARY, 1);   // 源码中JANUARY为0System.out.println(instance.get(Calendar.MONTH) + 1);// GregorianCalendar是Calendar的子类。提供比如判定闰年更为细致的操作}
}

*List

// 推荐下面写法。父类引用指向子类
List<String> list = new ArrayList<>();
// 1.面向接口编程,2.增加其灵活性。如果要修改ArrayList为LinkedList,方便 

List包括ArrayList、LinkedList。有序,可重复

public class ListExample {public static void main(String[] args) {// List<String> list2 = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));List<String> list = new ArrayList<>();list.add("Apple");list.add("Banana");list.add("Apple"); // 允许重复// 获取元素System.out.println("First element: " + list.get(0));// 删除元素list.remove(1);// List,和Set可以使用iterator()进行遍历// 如果要遍历后删除特定元素,使用iterator,而不要使用foreachIterator<String> iterator = list.iterator();while (iterator.hasNext()){if (iterator.next().equals("Banana")){iterator.remove();	}}/*为什么使用for-each会导致删除出现异常?for-each本质也是用iterator进行遍历集合,如果通过集合的方法(比如remove)修改集合,会导致集合结构被修改(modCount值发生变化)。从而触发ConcurrentModificationException。这是快速失败(fail-fast)机制,用于避免迭代器在集合结构被修改后行为不一致。/*}
}

数组到列表:最普通的方式,循环遍历加入list

// Demo1 : String类,或者 非基本数据类型
String[] array = {"a", "b", "c"};	
// 转化后的list固定大小的,只能修改元素,不能增删元素。源码AbstractList中的add()方法抛出异常
List<String> list = Arrays.asList(array);// 可变。ArrayList重写了AbstractList中的add()方法
List<String> arrayList = new ArrayList<>(Arrays.asList(array));
List<String> arrayList = new ArrayList<>(Arrays.asList("123", "abc"));// 同上
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList, array);		//  通过工具类进行操作/*
拓展: Arrays.asList(array)得到的List不可变?
sout(list.getClass().getName())可以得到java.util.Arrays$ArrayList
这个是ArrayList是Arrays的private类。因此最好也使用List接口去使用
而不是java.util.ArrayList*/// Demo2:  基本数据类型
int[] arr = {1, 2, 3};
/* 
由于int[]作为一个整体对象。如果是Integer[] 则为 ArrayList<Integer>
ArrayList<int[]> ints = new ArrayList<>(Arrays.asList(arr));
*/
List<Integer> collect = Arrays.stream(arr).boxed().collect(Collectors.toList());// Demo: int[]转化为List<Integer>int[] arr = {1, 2, 5, 3};
// 转为基本流,还有其他LongStream。对象流Stream<Object>
IntStream stream = Arrays.stream(arr);	
// 每个原始 int转换为对应的 Integer对象。Stream<Integer> integerStream = Stream.of(1, 2, 3);
Stream<Integer> boxed = stream.boxed();
// Collectors.toList()会返回List,从而被其收集。 List<Integer> collect = 
List<Integer> collect = boxed.collect(Collectors.toList());// 或者
stream.forEach(list::add);

Set包括HashSet、LinkedHashSet、TreeSet。无序,不重复

public class SetExample {public static void main(String[] args) {// Set<String> set2 = new HashSet<>(Arrays.asList("Apple", "Banana", "Cherry"));Set<String> set = new HashSet<>();set.add("Apple");set.add("Banana");set.add("Apple"); // 重复元素不会添加// 检查元素System.out.println("Contains Banana: " + set.contains("Banana"));// 遍历for (String item : set) {System.out.println("Item: " + item);}}
}

Map包括 HashMap、LinkedHashMap、TreeMap。键唯一,值可重复

public class MapExample {public static void main(String[] args) {/* Map<Integer, String> map2 = new HashMap<Integer, String>() {{put(1, "Apple");put(2, "Banana");put(3, "Cherry");}};实际创建一个HashMap子类的匿名内部类,然后执行双大括号的实例初始化块。ArrayList也可以,不推荐*/Map<Integer, String> map = new HashMap<>();map.put(1, "Apple");	// 推荐这种方法。map.put(2, "Banana");map.put(1, "Orange"); // 键重复时会覆盖旧值System.out.println("Map: " + map);// 获取值System.out.println("Value for key 1: " + map.get(1));// 遍历// map.entrySet().forEach((entry) -> System.out.println(entry.getKey() + entry.getValue()));for (Map.Entry<Integer, String> entry : map.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}// 把map转变为set(存储entry)后再iterator遍历Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();while (iterator.hasNext()){Map.Entry<Integer, String> next = iterator.next();System.out.println(next.getKey() + "---" + next.getValue() );}}
}

Vector

public class VectorExample {public static void main(String[] args) {Vector<String> vector = new Vector<>();vector.add("Apple");vector.add("Banana");vector.add("Cherry");System.out.println("Vector: " + vector);// 获取元素System.out.println("First element: " + vector.get(0));System.out.println("First element: " + vector.elementAt(0));// 删除元素vector.remove(1);System.out.println("After removal: " + vector);}
}

Random:不是线程安全的

  • 多线程或者频繁使用ThreadLocalRandom
  • 更加安全的类型SecureRandom
// 默认种子为System.nanoTime();
Random random = new Random();// 各种数据类型都可以随机
System.out.println(random.nextBoolean());
System.out.println(random.nextInt(100));// 填充byte[]
byte[] arr = new byte[5];
random.nextBytes(arr);
System.out.println(Arrays.toString(arr));

Scanner

  • 实际项目:如果要输出int,先判断是不是在输出。
  • nextLine问题:在调用next() 或者 nextInt() 后要处理回车
  • 使用后进行close,尤其是文件
// 从键盘中获取
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();	// 等待回车,表示一行
System.out.println("Hello " + s);// 从字符中读取
Scanner scanner1 = new Scanner("Java 123 3.14 true");
System.out.println(scanner1.next());	// 以空格和回车为分割
System.out.println(scanner1.nextInt());
System.out.println(scanner1.nextFloat());
System.out.println(scanner1.nextBoolean());// 从文件中读取
Scanner scanner = new Scanner(new File("data.txt"));
while (scanner.hasNextLine()){System.out.println(scanner.nextLine());
}scanner.close();

File

// 常用方法。exists,createNewFile, getAbsolutePath,delete
File file = new File("example.txt");
if (!file.exists()){if(file.createNewFile()){System.out.println("File created " + file.getAbsolutePath());}else {System.out.println("File creation failed");}
} else {System.out.println("File already exists");
}if (file.delete()){System.out.println("File deleted");
}

File*的IO

// Demo1: 基本fos/fis 和 fw/fr
FileInputStream fis = new FileInputStream("data.txt")
int content ;
while ((content = fis.read()) != -1){System.out.print((char) content);
}FileOutputStream fos = new FileOutputStream("data.txt")
// 字节流fos.write 只接受bytes[] 和 int。所以其他的要先转化为bytes
fos.write("Hello World".getBytes());    // 会清空之前的文件内容FileReader fr = new FileReader("data.txt")	// 和fis一模一样
int content;
while ((content = fr.read()) != -1){System.out.print((char)content);
}FileWriter fw = new FileWriter("data.txt")
// 字符流fw.write 可以接受多种,
fw.write("Hello World!");// Demo2: 文本拷贝
try (FileInputStream fis = new FileInputStream("data.txt");FileOutputStream fos = new FileOutputStream("destination.txt")){//            int content ; 等效下面//            while ((content = fis.read()) != -1){//                fos.write((char) content);//            }byte[] buff = new byte[1024];int length;while ((length = fis.read(buff)) != -1){	// BUffer*也可以使用此fos.write(buff, 0 , length); // 打印:new String(buff, 0, length)}
} 

javafx

javaFX : Foundation Classes Extension

  • 由于awt和swing过时

  • JavaFX 支持 CSS 和 FXML

基本Demo

/*
start() 是 JavaFX 应用程序的主要逻辑入口,用于设置 UI。
launch(args) 是 JavaFX 框架中用于启动应用程序的静态方法。并初始化 JavaFX 的运行环境、设置事件调度线程(JavaFX 应用主线程),并最终调用 start() 方法。
args即便未用到,也是一种规范的调用方式。
*/public class JavaFXExample extends Application {@Overridepublic void start(Stage primaryStage) {// 设置标题primaryStage.setTitle("JavaFX 示例");// 创建标签按钮。 注意都是javafx下,而不是awt下Label label = new Label("Hello, JavaFX!");Button button = new Button("点击我");button.setOnAction(event -> label.setText("按钮被点击了!"));// 使用 VBox 布局,其实就是容器,用于放控件VBox vbox = new VBox(10); // 布局间距为 10 像素vbox.getChildren().addAll(label, button);// 创建场景 (Scene)用于展示Scene scene = new Scene(vbox, 300, 200); // 宽 300 高 200primaryStage.setScene(scene);// 显示窗口primaryStage.show();}public static void main(String[] args) {launch(args); // 启动 JavaFX 应用程序}
}

登录Demo

primaryStage.setTitle("登录窗口");// 创建布局
GridPane gridPane = new GridPane();
gridPane.setHgap(10); // 设置水平间距
gridPane.setVgap(10); // 设置垂直间距// 添加控件
Label usernameLabel = new Label("用户名:");
TextField usernameField = new TextField();Label passwordLabel = new Label("密码:");
PasswordField passwordField = new PasswordField();Button loginButton = new Button("登录");
Label messageLabel = new Label();// 登录按钮事件
loginButton.setOnAction(event -> {String username = usernameField.getText();String password = passwordField.getText();if ("admin".equals(username) && "123".equals(password)) {messageLabel.setText("登录成功!");} else {messageLabel.setText("用户名或密码错误!");}
});// 将控件添加到布局中
gridPane.add(usernameLabel, 0, 0);
gridPane.add(usernameField, 1, 0);
gridPane.add(passwordLabel, 0, 1);
gridPane.add(passwordField, 1, 1);
gridPane.add(loginButton, 1, 2);
gridPane.add(messageLabel, 1, 3);// 创建场景
Scene scene = new Scene(gridPane, 300, 400);
primaryStage.setScene(scene);
primaryStage.show();

java.net

URL

// Demo: 通过url访问网页内容
URL url = new URL("http://example.com");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String s;
while ((s = br.readLine()) != null){System.out.println(s);
}
br.close();

HttpCookie

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);HttpCookie httpCookie = new HttpCookie("username", "adair");
httpCookie.setDomain("example.com");
httpCookie.setPath("/");// 添加cookie到CookieManager
URI uri = new URI("http://example.com");
cookieManager.getCookieStore().add(uri, httpCookie);// 输出cookie
System.out.println(cookieManager.getCookieStore().get(uri));
// 输出:[username="adair";$Path="/";$Domain="example.com"]

范围修饰符

访问范围

顶级类必须是 public 或者包级 default

修饰符方法变量
public任何地方`任何地方`任何地方
protected只能修饰嵌套类同包内、子类中可以访问同包内、子类中可以访问
default只能在同包内访问只能在同包内访问只能在同包内访问
private不能修饰顶级类只能在当前类内访问只能在当前类内访问
// public 
public class MyClass {public void myMethod() {System.out.println("This is a public method.");}// protected方法protected void myMethod() {System.out.println("This is a protected method.");}// privateprivate void myMethod() {System.out.println("This is a private method.");}
}// default,但是可以写default关键字	
class MyClass { // 默认访问权限void myMethod() {System.out.println("This is a default method.");}
}

泛型

泛型不可变:是指List和 List 没有任何关系,也没继承关系。

// Demo1 : 泛型类,
public class Box<T> {	// 可以传递多个泛型, <T, R>private T value;public void setValue(T value) {this.value = value;}public T getValue() {return value;}
}Box<String> stringBox = new Box<>();	// 可以String,也可以是Integer

泛型方法

// 返回值前面加上<T>
public static <T> void printArray(T[] array) {for (T element : array) {System.out.println(element);}
}String[] names = {"Alice", "Bob"};
Integer[] numbers = {1, 2, 3};printArray(names);  // 推断 T 为 String
printArray(numbers); // 推断 T 为 Integer

有界泛型

// T 只能是 Number 或其子类,比如 Integer 或 Double。
class Box<T extends Number> {private T value;
}// 下界是 Integer,即列表可以接受 Integer 或其父类(如 Number)
public static void addNumber(List<? super Integer> list) {list.add(42);
}/*T extend ClassA 表示ClassA的子类? super ClassA	表示ClassA的父类
*/

有界泛型例子demo1:如何使用

// 
class Animal {String name;Animal(String name) {this.name = name;}
}
// 实现的Comparable<Animal>,并非Comparable<Dog>,因为只要父类可以比较,子类就可以找其父进行比较
class Dog extends Animal implements Comparable<Animal> {Dog(String name) {super(name);}@Overridepublic int compareTo(Animal o) {return name.compareTo(o.name); // name继承父类的name}@Overridepublic String toString() {return name;}
}public class Main {/*U extends Comparable 表示 U 必须实现 Comparable 接口。<? super U> 限定了 Comparable 接口对象,表示 U 或 U 的父类(更通用)。<U extends Comparable<U>> 则表示只接受U类型,并且U实现排序。<U extends Comparable<? super U>> 表示U的父类实现Comparable即可*/public static <U extends Comparable<? super U>> void sortList(List<U> list) {list.sort(Comparator.naturalOrder()); // 使用自然排序}public static void main(String[] args) {// 只能定义为Dog,不能Animal,因为父类压根没实现ComparableList<Dog> dogs = Arrays.asList(new Dog("Charlie"), new Dog("Buddy"), new Dog("Max"));sortList(dogs); // 排序方法被成功调用System.out.println(dogs); // 输出结果按名字排序:Buddy, Charlie, Max}
}

有界泛型例子demo1:

public class Main {public static <U extends Comparable<? super U>> void sortList(List<U> list) {list.sort(Comparator.naturalOrder()); // 使用自然排序}public static void main(String[] args) throws Exception {ArrayList<Animal> list = new ArrayList<>();// 添加Dog 和 Catlist.add(new Dog("Bob"));list.add(new Cat("Alice"));sortList(list);System.out.println(list);}}class Dog extends Animal{public Dog(String name) {super(name);}
}class Cat extends Animal{public Cat(String name) {super(name);}
}class Animal implements Comparable<Animal>{String name;public Animal(String name) {this.name = name;}@Overridepublic int compareTo(Animal o) {return name.compareTo(o.name);}@Overridepublic String toString() {return name;}
}

经典例子

序列化

作用:

  • 常用于存储:比如持久化(存在文件或者数据库),远程通信RMI,缓存等
  • transientstatic 字段不会被序列化。比如密码,使用 transient 关键字避免暴露
public class Main {public static void main(String[] args) throws Exception {Person adair = new Person("Adair", 18, "123456");ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(Paths.get("demo.txt")));oos.writeObject(adair);System.out.println(adair);      // 会输出密码ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo.txt"));Person person = (Person)ois.readObject();System.out.println(person);     // 密码 passworld = null}
}class Person implements Serializable {	// 仅仅标记Serializable,类似于Cloneable// 用于查看版本private static final long serialVersionID = 2L;String name;int age;transient String password;public Person(String name, int age, String password) {this.name = name;this.age = age;this.password = password;}@Overridepublic String toString() {return "name = " + name + ", age = " + age + ", password = " + password;}
}

拓展:如果序列化之后可以让人读的话,可以使用JSON

/*implementation("com.google.code.gson:gson:2.10.1") 引入json库Person不用接口Serializable
*/
Person adair = new Person("Adair", 18, "123456");
Gson gson = new Gson();
String json = gson.toJson(adair);BufferedWriter bw = new BufferedWriter(new FileWriter("demo.txt"));
bw.write(json);
bw.flush();                     // 确保数据写入文件,一定要做
System.out.println(json);       // {"name":"Adair","age":18}。没有密码BufferedReader br = new BufferedReader(new FileReader("demo.txt"));
System.out.println(br.readLine());          // 同上br.close();		// 流的类,都要进行关闭
bw.close();

线程:生产者消费者

public class Demo2 {public static void main(String[] args) {SharedBuffer sharedBuffer = new SharedBuffer();// 同一个sharedBuffer, 生产者和消费者两个线程进行执行new Thread(new Producer(sharedBuffer)).start();new Thread(new Consumer(sharedBuffer)).start();}
}class SharedBuffer {private boolean avalible = false;   // 标志位,表示是否有产品// 生产产品,public synchronized void produce(int id) throws InterruptedException {while (avalible){   // 等待至消费者消费结束wait();     // 即this.wait();  线程等待;释放锁(资源),其他线程可以获取该锁。}System.out.println("produce: " + id);avalible = true;    // 标记产品可用notify();      // 随机唤醒一个线程,此处必然是唤醒消费者的wait();}// 消费商品public synchronized void consume(int id) throws InterruptedException {while (!avalible){wait();}System.out.println("consume: " + id);avalible = false;notify();}
}class Producer implements Runnable{SharedBuffer sharedBuffer;public Producer(SharedBuffer sharedBuffer) {this.sharedBuffer = sharedBuffer;}@Overridepublic void run() {try {for (int i = 0; i < 5; i++) {sharedBuffer.produce(i);Thread.sleep(500);  // 模拟生产过程}} catch (InterruptedException e) {throw new RuntimeException(e);}}
}class Consumer implements Runnable{SharedBuffer sharedBuffer;public Consumer(SharedBuffer sharedBuffer) {this.sharedBuffer = sharedBuffer;}@Overridepublic void run() {try {for (int i = 0; i < 5; i++) {sharedBuffer.consume(i);Thread.sleep(500);}} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

Comparator:对象排序

List<Person> list = Arrays.asList(new Person("Alice", 25),new Person("Bob", 30),new Person("Alice", 20)
);
Comparator<Person> personComparator = Comparator.comparing((Person p) -> p.name).thenComparing((Person p) -> p.age);
list.sort(personComparator);
System.out.println(list);// 源码:参数为Function的lambda,返回为Comparator的lambda
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor)
{Objects.requireNonNull(keyExtractor);return (Comparator<T> & Serializable)(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
// 返回一个Comparator<T>类型的比较器,
// 值为(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));此为lambda表达式
// 并且需要强转为Comparator<T> & Serializable
// Serializable接口表示可以序列化

单例和多例

单例

  • 确保一个类只有一个实例,提供统一的访问方式(通常是一个静态方法)
  • 应用:日志、数据库连接池、配置文件管理。

饿汉式和懒加载(懒汉式)

public class Singleton {// private方式被newprivate Singleton() {}// 懒加载:节省资源private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}public class Singleton {private Singleton() {}// 饿汉式,只要加载类就可以private static final Singleton INSTANCE = new Singleton();public static Singleton getInstance() {return INSTANCE;}
}

多例

  • 允许一个类拥有多个实例,但限制实例数量,每个实例可以通过特定的标识符获取(比如键值)。
  • 应用:数据库分区管理、缓存对象
// 多例模式的实现
class Multiton {private static final Map<String, Multiton> instances = new HashMap<>();private final String name;private Multiton(String name) {	// 私有构造方法,防止被newthis.name = name;}// 获取实例的方法public static Multiton getInstance(String key) {instances.putIfAbsent(key, new Multiton(key)); // 每个 key 只会创建一次return instances.get(key);}}// 测试类
public class Main {public static void main(String[] args) {Multiton instance1 = Multiton.getInstance("DB1");Multiton instance2 = Multiton.getInstance("DB2");Multiton instance3 = Multiton.getInstance("DB1"); // 获取已存在的实例,等instance1}
}

标签

outer: for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {// 表示外层breakif (i == 1) break outer;	System.out.println(i + " " +j);	// 0 0、0 1、0 2}
}outer: for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {// 外层continueif (i == 1) continue outer;	// 0 0、0 1、0 2、2 0、2 1、2 2System.out.println(i + " " +j);	}
}

枚举

class FreshJuice{enum FreshJuiceSize{ SMALL, MEDIUM, LARGE};FreshJuiceSize size;	// 自定义的数据类型
}public class EumExample{public static void main(String[] args){FreshJuice juice = new FreshJuice();juice.size = FreshJuice.FreshJuiceSize.MEDIUM;System.out.println(juice.size);}
}

内部类

成员内部类、静态内部类、局部内部类、匿名内部类

// 成员内部类
public class OuterClass {pulic class InnerClass{public void display{sout("hello");}}
}
InnerClass example = new OuterClass().new InnerClass();
example.display();// 静态内部类,就是改为 pulic static class InnerClass
InnerClass example = new InnerClass();
example.display();// 局部内部类:就是方法里面定义的类,然后此方法使用这个类// 匿名内部类:new Interface()然后实现方法。这个实现接口且没有名字的实例,就叫匿名内部类。

instanceof

public class Test {public static void main(String[] args) {Object os = new Student();System.out.println(os instanceof Object);//1System.out.println(os instanceof Person);//1System.out.println(os instanceof Student);//1System.out.println(os instanceof Teacher);//0System.out.println(os instanceof String);//0Person ps = new Student();System.out.println(ps instanceof Object);//1System.out.println(ps instanceof Person);//1System.out.println(ps instanceof Student);//1System.out.println(ps instanceof Teacher);//0
//        System.out.println(ps instanceof String); //报错Student ss = new Student();System.out.println(ss instanceof Object);//1System.out.println(ss instanceof Person);//1System.out.println(ss instanceof Student);//1
//        System.out.println(ss instanceof Teacher); //报错
//        System.out.println(ss instanceof String);  //报错}
}

BigDecimal


BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
BigDecimal subtract = bd1.subtract(bd2);//add,multiply,divide
System.out.println(subtract);   //0.1BigDecimal divide = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(divide);     //1//除不尽,如果不四舍五入的话,报错
BigDecimal divide1 = new BigDecimal("10").divide(new BigDecimal("3"), 2, BigDecimal.ROUND_HALF_UP);
System.out.println(divide1);    //3.33

assert

用于调试使用,如果不符合条件运行直接异常。需要在VM options中增加-ea(enable assert)。

// assert
public class Demo2 {public static void main(String[] args) {// 设置初始值String s = null;// 判断s值是否为空,并用assert赋值boolean。结果为false。assert s==null?false:true;System.out.println("end");}
}
public class VolatileTest {// 如果flag没有volatile,则Thread1卡在while中volatile boolean flag = true;public void updateFlag() {this.flag = false;System.out.println("修改flag值为:" + this.flag);}public static void main(String[] args) {VolatileTest test = new VolatileTest();new Thread(() -> {while (test.flag) {	}System.out.println(Thread.currentThread().getName() + "结束");}, "Thread1").start();new Thread(() -> {try {Thread.sleep(2000);test.updateFlag();} catch (InterruptedException e) {}}, "Thread2").start();}
}

测试单元

import org.junit.Test;
import static org.junit.Assert.*;public class ExampleUnitTest {@Test	// 表示这是一个测试例子,可以单独运行public void addition_isCorrect() {// 测试一个简单的加法函数assertEquals(4, 2 + 2);}// 测试是否有相应的异常@Test(expected = ArithmeticException.class)public void division_byZero() {int result = 1 / 0;}    
}

测试单元:

  • 必须是 public 修饰的。
  • 必须是 void 返回类型。
  • 不能有参数。

其他

输出解释

// 在直接输出对象(即toString()),Object[][][]输出[[[Ljava.lang.Object;   
// L表示对象的引用,后面表示Hash值
[Ljava.lang.Object@74a14482;// 比如 [I 表示int[]。 [Ljava.lang.String;表示String[]

字符串

// 正则表达式。这个用于判定纯数字
str.matches("\\d+")

常用方法:

LocalDateTime.now();	// 获取当前时间
Thread.currentThread().getName();	// 当前 

有待解决

strictfp:用于修饰接口、类、方法用于浮点数的精确计算。strict interface MyInterface/class MyClass/int myMethod。不能用于修饰接口的方法。

new Student();
System.out.println(ss instanceof Object);//1
System.out.println(ss instanceof Person);//1
System.out.println(ss instanceof Student);//1
// System.out.println(ss instanceof Teacher); //报错
// System.out.println(ss instanceof String); //报错

}

}


## BigDecimal```javaBigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
BigDecimal subtract = bd1.subtract(bd2);//add,multiply,divide
System.out.println(subtract);   //0.1BigDecimal divide = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(divide);     //1//除不尽,如果不四舍五入的话,报错
BigDecimal divide1 = new BigDecimal("10").divide(new BigDecimal("3"), 2, BigDecimal.ROUND_HALF_UP);
System.out.println(divide1);    //3.33

assert

用于调试使用,如果不符合条件运行直接异常。需要在VM options中增加-ea(enable assert)。

// assert
public class Demo2 {public static void main(String[] args) {// 设置初始值String s = null;// 判断s值是否为空,并用assert赋值boolean。结果为false。assert s==null?false:true;System.out.println("end");}
}
public class VolatileTest {// 如果flag没有volatile,则Thread1卡在while中volatile boolean flag = true;public void updateFlag() {this.flag = false;System.out.println("修改flag值为:" + this.flag);}public static void main(String[] args) {VolatileTest test = new VolatileTest();new Thread(() -> {while (test.flag) {	}System.out.println(Thread.currentThread().getName() + "结束");}, "Thread1").start();new Thread(() -> {try {Thread.sleep(2000);test.updateFlag();} catch (InterruptedException e) {}}, "Thread2").start();}
}

测试单元

import org.junit.Test;
import static org.junit.Assert.*;public class ExampleUnitTest {@Test	// 表示这是一个测试例子,可以单独运行public void addition_isCorrect() {// 测试一个简单的加法函数assertEquals(4, 2 + 2);}// 测试是否有相应的异常@Test(expected = ArithmeticException.class)public void division_byZero() {int result = 1 / 0;}    
}

测试单元:

  • 必须是 public 修饰的。
  • 必须是 void 返回类型。
  • 不能有参数。

其他

输出解释

// 在直接输出对象(即toString()),Object[][][]输出[[[Ljava.lang.Object;   
// L表示对象的引用,后面表示Hash值
[Ljava.lang.Object@74a14482;// 比如 [I 表示int[]。 [Ljava.lang.String;表示String[]

字符串

// 正则表达式。这个用于判定纯数字
str.matches("\\d+")

常用方法:

LocalDateTime.now();	// 获取当前时间
Thread.currentThread().getName();	// 当前 

有待解决

strictfp:用于修饰接口、类、方法用于浮点数的精确计算。strict interface MyInterface/class MyClass/int myMethod。不能用于修饰接口的方法。

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

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

相关文章

JDBC实验测试

一、语言和环境 实现语言&#xff1a;Java。 环境要求&#xff1a;IDEA2023.3、JDK 17 、MySQL8.0、Navicat 16 for MySQL。 二、技术要求 该系统采用 SWING 技术配合 JDBC 使用 JAVA 编程语言完成桌面应用开发。 三、功能要求 某电商公司为了方便客服查看用户的订单信…

小程序获取微信运动步数

1、用户点击按钮&#xff0c;在小程序中触发getuserinfo方法&#xff0c;获取用户信息 <scroll-view class"scrollarea" scroll-y type"list"><view class"container"><button bind:tap"getLogin">获取</button&…

macOS 安装JDK17

文章目录 前言介绍新特性下载安装1.下载完成后打开downloads 双击进行安装2.配置环境变量3.测试快速切换JDK 小结 前言 近期找开源软件&#xff0c;发现很多都已经使用JDK17springboot3 了&#xff0c;之前的JDK8已经被替换下场&#xff0c;所以今天就在本机安装了JDK17&#…

Windows电脑桌面记录日程安排的提醒软件

在快节奏的现代生活中&#xff0c;工作效率成为了衡量个人能力的重要标准之一。然而&#xff0c;日常办公中常常会遇到各种琐事和任务&#xff0c;如果没有合理安排日程&#xff0c;很容易陷入混乱&#xff0c;导致效率低下。因此&#xff0c;做好日程安排对于日常工作至关重要…

MFC 使用 32位带Alpha通道的位图

最近需要做一个MFC界面上的图片,众所周知,MFC 好像只支持 bmp 格式的! 先看我的原始24位图片,RGB 三个颜色各占8位 (256色), 所以是24位。 如果放到MFC界面上,是这个很丑的效果 它是一个正方形图片,周围的白色可以看见。 解下来,进入今天的主题: 32位带 Alpha 通…

Ubuntu22部署MySQL5.7详细教程

Ubuntu22部署MySQL5.7详细教程 一、下载MySQL安装包二、安装MySQL三、启动MySQL 检查状态登录MySQL 四、开启远程访问功能 1、允许其他主机通过root访问数据库2、修改配置文件&#xff0c;允许其他IP通过自定义端口访问 五、使用Navicat连接数据库 默认情况下&#xff0c;Ubun…

大模型 | AI驱动的数据分析:利用自然语言实现数据查询到可视化呈现

【本文作者&#xff1a;擎创科技资深产品专家 布博士】 在当今AI驱动的时代&#xff0c;数据分析已成为各行各业不可或缺的能力。然而&#xff0c;传统的数据分析流程通常需要掌握SQL、数据处理和可视化等多项专业技能&#xff0c;这对非技术背景的业务人员来说是一个不小的挑…

C++ ——— 模拟实现 vector 类

目录 vector 类的框架 无参数的构造函数 析构函数 获取有效数据个数 获取容量 重载 [] 运算符 可读可写版本 只可读版本 扩容 尾插 实现迭代器 可读可写版本 只可读版本 自定义设置size长度和内容 在任意位置插入 删除任意位置的数据 赋值重载 vector 类的框…

Git处理冲突详解

文章目录 Git处理冲突详解一、引言二、冲突产生的原因三、解决冲突的步骤1. 手动解决冲突1.1 查看冲突文件1.2 编辑冲突文件1.3 提交解决冲突 2. 使用合并工具解决冲突 四、使用示例五、总结 Git处理冲突详解 一、引言 在团队协作开发中&#xff0c;Git冲突是不可避免的。当多…

GS论文阅读--GeoTexDensifier

前言 本文是一个关于高斯致密化策略对高斯地图进行优化&#xff0c;他主要关注了几何结构和纹理信息。我最近对于高斯点的分布比较感兴趣&#xff0c;因为高斯点的分布决定了之后重建质量的好坏&#xff0c;初始化高斯很重要&#xff0c;但之后的维护需要致密化与修建策略&…

【云原生布道系列】第三篇:“软”饭“硬”吃的计算

1 虚拟化技术定义 首先援引一段《虚拟化技术发展编年史》中针对虚拟化技术的定义&#xff1a;在计算机科学中&#xff0c;虚拟化技术&#xff08;Virtualization&#xff09;是一种资源管理&#xff08;优化&#xff09;技术&#xff0c;将计算机的各种物理资源&#xff08;例如…

Java虚拟机面试题:内存管理(中)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

Linux容器(初学了解)

目录 一、容器 1.1、容器技术 1.2、容器和虚拟机之间的差异 1.3、Rootless 和 Rootful 容器 1.4、设计基于容器的架构 1.5、容器管理工具 1.6、容器镜像和注册表 1.7、配置容器注册表 1.8、使用容器文件构建容器镜像 二、部署容器 2.1、Podman 实用程序 2.2、安装容…

代码随想录_字符串

字符串 344.反转字符串 344. 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。 思路: 双指针 代…

Visual Studio Community 2022(VS2022)安装方法

废话不多说直接上图&#xff1a; 直接上步骤&#xff1a; 1&#xff0c;首先可以下载安装一个Visual Studio安装器&#xff0c;叫做Visual Studio installer。这个安装文件很小&#xff0c;很快就安装完成了。 2&#xff0c;打开Visual Studio installer 小软件 3&#xff0c…

PostgreSQL的学习心得和知识总结(一百六十六)|深入理解PostgreSQL数据库之\watch元命令的实现原理

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

在k8s中部署一个可外部访问的Redis Sentinel

1.前提条件&#xff1a; 1.部署了multus 想要k8s外部能访问k8s内部的redis&#xff0c;redis-server启动时必须使用multus的IP 2.helm客户端安装 2.开始安装 准备3个multus ip 10.10.10.130 10.10.10.131 10.10.10.132 apiVersion: k8s.cni.cncf.io/v1 kind: NetworkAttac…

目标跟踪算法发展简史

单目标跟踪&#xff08;Single Object Tracking&#xff0c;SOT&#xff09;是计算机视觉领域中的一个重要研究方向&#xff0c;旨在在视频序列中持续定位并跟踪一个特定目标。随着计算机视觉和机器学习技术的飞速发展&#xff0c;单目标跟踪算法经历了从经典方法到深度学习的演…

使用LPT wiggler jtag自制三星单片机(sam88 core)编程器-S3F9454

写在前面 新年好&#xff0c;各位&#xff0c;今天来分享制作一个三星单片机的编程器 嘿嘿&#xff0c;x鱼垃圾佬元件库有些三星单片机s3f9454&#xff0c;编程器不想买&#xff0c;基本拿来拆件玩的。但&#xff0c;前些时候csdn下载到它的编程时序&#xff0c;自己来做个编程…

Spring 中的事件驱动模型

事件驱动的基本了解 事件模式也就是观察者模式&#xff0c;当一个对象改变的时候&#xff0c;所有依赖的对象都会收到一个通知。 Subject&#xff1a;抽象主题 Observer&#xff1a;具体主题 Concrete Subject&#xff1a;抽象观察者&#xff0c;在得到更新通知之后去更新自…