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

Java笔记

String、StringBuilder、StringBuffer
String不可变,StringBuilder和StringBuffer可变,只有StringBuffer是线程安全的。
String不可变的四个原因:
(1)类被final修饰不可被继承
(2)底层char[]数组被final修饰
(3)提供的方法返回值都是new一个新String对象
(4)字符串常量池可知,程序中字符串指向同一个对象,如果字符串可变,那么改变一个,另一个也会改变。
String的append方法与String不可变冲突吗:
不冲突!拼接字符串底层是用StringBuilder的append方法,而StringBuilder底层是调用AbstractStringBuilder方法的append方法,拼接的时候是复制char[]来实现append。最后返回是一个new String对象。
StringBuffer如何保证线程安全:
StringBuffer的方法用Synchronized声明了,是线程安全的。
"a"+"b":底层是new一个StringBuilder出来append字面量a和字面量b。
字符串常量什么时候被加载到字符串常量池中的:
对于这种字面量在编译的时候会加入class常量池中,然后运行期间首次被调用的时候才会在字符串常量池中创建一个String对象,也就是此时加入字符串常量池。
对于字符串常量池中字符串来源有两种,第一个是字面量在运行期间首次调用加入字符串常量池,第二个是运行期间将普通字符串对象通过intern方法加入。
String s = new String("a"); 请问创建了几个对象:
如果是第一次执行,则创建两个:创建一个字符串“a”放到字符串常量池中,然后在堆内存中创建一个对象,这个对象是字符串常量池中“a”的引用。
如果是第二次执行,则创建一个:创建一个对象指向字符串常量池中的对象。
String s = "ab"; String ss = "a"+"b"; sss结果是什么:
由于有字符串常量池的存在,s和ss都是字符串常量池中“ab”字面量的一个引用,而在java中
比较的是地址,所以返回的是true。
String 有长度限制吗?
编译器与运行期不同。编译器表示CONSTANT_utf8_info表示字符串常量,限制2^16-1=65535.
运行期String的length属性是int类型,最大2^31-1.
java的各类常量池
a. Class常量池Constant Pool:
类编译成.class文件后会将字面量、符号引用放到class常量池中(编译期间),class常量池中的内容运行的时候会加载到常量池中(运行期间)。通过javap命令查看内容:javap -v xxx.class
b. 运行时常量池Runtime Constant Pool:
它是java虚拟机中的一个逻辑区域,或者说是一种规范,它指定运行时的常量、符号引用等数据应该放在运行时常量池,HotPot虚拟机就把它给实现了,放在了方法区。
c. 字符串常量池:
它是运行时常量池的一块逻辑子区域的一个具体实现,jdk1.7之后它位于堆内存。因为运行时常量池规定常量要可以做到复用,所以它存储的是字符串常量。
java有基本类型为什么还需要包装类
a. java面向对象,集合要求元素是Object对象
b. 包装类型相比基本类型有了更多的属性与方法,支持更多操作
c. RPC接口返回中使用的是包装类型,可以避免歧义
自动拆箱与装箱
基本数据类型与包装类型之间的转换。
例如:List里面放int
java中接口与抽象类的区别
a. 最主要的区别:接口用于制定规范,抽象类用于抽象出通用模板
b. 编码规范的区别:接口可以多实现,抽象类只能单继承;接口是对外公开的,修饰符都是public,抽象类修饰符没有限制;接口不能有私有方法与变量,抽象类可以有;接口的设计主要自顶而下,一般是先对下游提供接口文档,然后对接口做不同的实现。抽象类的设计主要自底而上,基于模板方法抽象出公共逻辑再扩充。
java的多态
a. 多态是一种运行期概念,同一种动作作用于不同对象会产生不同结果
b. 多态产生的条件:子类继承父类or实现接口、子类重写父类的方法、父类引用指向子类对象;
java的泛型
a. 定义类或者接口的时候使用类型作为参数
b. 作用:参数是类型参数,可以提高复用性;安全性,因为编译期间可以做类型检查,否则如果运行期间出现类型转换异常程序可能直接退出。
c. 类型擦除:编译之后的字节码文件中会将类型信息擦除。

ConcurrentHashMap
https://blog.csdn.net/Mind_programmonkey/article/details/111035733
HashMap不是线程安全的,HashTable是线程安全的,但是会使用Synchronized锁住整张表来保证强一致性,ConcurrentHashMap使用锁分段来降低锁粒度来提升并发性能,它在读的过程不加锁,写的过程加锁。
JDK 1.7:ConcurrentHashMap有两个内部类:HashEntry、Segment。它是一个Segment数组,而每个Segment元素又是一个HashEntry数组,HashEntry数组中每个元素的位置都是一个单向链表的头节点,由于HashEntry内部的next属性是final,所以插入元素使用头插法。
由于Segment继承了Reentrantlock,所以他本身就是一把锁,上锁的时候锁的是Segment。

JDK 1.8:取消了Segment,整体是HashEntry数组,锁粒度是单个HashEntry:当桶节点为空,则使用CAS+Synchronized的操作插入数据。如果桶节点不为空,则使用synchronized锁住桶节点,再插入数据
(1)为什么使用synchronized而不是reentrantlock?
答:
1、synchronized不需要手动加锁解锁
2、syn是JVM内置语义,编译器层面可以进行优化,例如锁粗化,锁消除
3、syn本身有一个锁升级的过程,加锁失败的线程不会挂起,在轻量级锁下而会自旋获取锁,减少线程唤醒的开销,只有重量级锁才会阻塞。
4、syn加锁的开销都没有reen那么大,只需要操作对象头或者监视器锁即可。
(2)ConcurrentHashMap的数据结构:
Map是由Segment数组+Entry数组+链表。一个Segment就是一张哈希表,Segment继承了ReenTrantlock,自己就是一个锁。

JDK 1.7中,ConcurrentHashMap查找元素需要两次定位,第一次定位到指定的Segment,第二次从Segment定位到元素所在链表的头部。这在提高并发性能的同时会导致Hash时间过长,并且最高同时支持Segment数量大小的写操作
JDK 1.8 (Java 8)中,进一步降低锁的粒度,对节点进行加synchronized锁,使用CAS算法
(3)ConcurrentHashMap中变量使用final和volatile修饰有什么用呢?
使用final:确保初始化的线程安全
使用volatile来保证某个变量内存的改变对其他线程的可见性,在配合CAS操作的原子性可以实现不加锁对并发操作的支持。
例如,get操作可以无锁是由于Node的元素val和指针next是用volatile修饰的,在多线程环境下线程A修改结点的val或者新增节点的时候是对线程B可见的
(4)ConcurrentHashMap有什么缺陷吗?
同步读取操作则是完全非阻塞的。好处是在保证合理的同步前提下,效率很高。坏处是严格来说读取操作不能保证反映最近的更新。例如线程A调用putAll写入大量数据,期间线程B调用get,则只能get到目前为止已经顺利插入的部分数据。
(5)ConcurrentHashMap在JDK 7和8之间的区别
● JDK1.8的实现降低锁的粒度,JDK1.7版本锁的粒度是基于Segment的,包含多个HashEntry,而JDK1.8锁的粒度就是HashEntry(首节点)
● JDK1.8版本的数据结构中没有Segment了,只有桶数组,因为已经使用synchronized来进行同步,所以不需要分段锁的概念,也就不需要Segment这种数据结构了,由于粒度的降低,实现的复杂度也增加了
● JDK1.8使用红黑树来优化链表,基于长度很长的链表的遍历是一个很漫长的过程,而红黑树的遍历效率是很快的,代替一定阈值的链表(6和8就是阈值,不选7是防止频繁切换),这样形成一个最佳拍档
(6)HashMap如何实现线程安全问题
答:(1)使用Collections.synchronized(new HashMap<>()) 使其变成一个线程安全的Map。底层做的事情是用synchronized锁住整个Map
(2)降低锁粒度,封装一个HashMap,使用ReadWriteLock(互斥写锁、共享读锁)封分别封装put方法和get方法。
(3)ConcurrentHashMap
3、HashMap的认识
(1)HashMap的数据结构:
HashMap实际是一个桶数组,它底层使用拉链式散列算法解决哈希冲突,也就是用数组+链表/红黑树构成的,数组是主体,链表或者红黑树用来解决hash冲突,数组是Entry类型,每一个Entry包含key-value队。一个hash表就是一个数组,每个元素是哈希桶
(2)get方法:

  1. 首先,需要计算键的哈希值,并通过哈希值计算出在数组中的索引位置(桶的位置)。
  2. 如果该位置上的元素为空,说明没有找到对应的键值对,直接返回null。
  3. 如果该位置上的元素不为空,遍历该位置上的元素,如果找到了与当前键相等的键值对,那么返回该键值对的值,否则返回null。
    (3)put方法:
  4. 首先,put方法会计算键的哈希值(通过调用hash方法),并通过哈希值计算出在数组中的索引位置。
  5. 如果该位置上的元素为空,那么直接将键值对存储在该位置上。
  6. 如果该位置上的元素不为空,那么遍历该位置上的元素,如果找到了与当前键相等的键值对,那么将该键值对的值更新为当前值,并返回旧值。
  7. 如果该位置上的元素不为空,但没有与当前键相等的键值对,那么将键值对插入到链表或红黑树中(如果该位置上的元素数量超过了8,就会将链表转化为红黑树来提高效率)。
  8. 如果插入成功,返回被替换的值;如果插入失败,返回null。
  9. 插入成功后,如果需要扩容,那么就进行一次扩容操作。
    (4)计算桶数组的位置公式:
    hashmap定位数组索引哈希桶位置公式:(table.length - 1) & (key.hashCode ^ (key.hashCode >> 16))
    X%table.length 等价于 X&(table.length-1),因为与运算效率高
    X=(key.hashCode ^ (key.hashCode >> 16)),原因:
    防止低位相同而高位不相同导致计算的hash值相同,例如容量是16,那么length-1=1111,它与运算的结果只取决于第四位,如果第四位相等则hash相等,这种碰撞概率很大。
    因此我们让让hashcode的高十六位与第十六位异或,是一种哈希扰动,相当于把高16位信息保存下来了,可以增加随机性,减少哈希碰撞。
    (5)为什么容量必须是2的n次方:
    第一,转化为与运算效率最高。第二,保证均匀性,减少hash碰撞,例如容量是17,X&(17-1),最后的结果只有16和0,这样大大增加哈希碰撞概率。
    (6)链表与红黑树转化:
    哈希桶元素个数大于8转红黑树,8的原因是官方假设hash函数服从泊松分布,元素个数为8的概率非常非常小,而红黑树虽然在元素多的情况下能够提升查询的效率,但是它的存储容量也是链表的两倍,因此只有在小概率事件上才会转红黑树。
    哈希桶元素个数小于6转链表,6的原因是防止链表与红黑树的频繁转换,这样耗费性能。
    (7)redis与hash的关联:一个redis就是一张全局hash表
    redis就是一个dictEntry数组,dictEntry内容如图:key是SDS、value是redisObject
    结构一共定义了 4 个元数据和一个指针:
    type:redisObject 的数据类型,面向用户的数据类型(String/List/Hash/Set/ZSet等)。占用 4 bit
    encoding:redisObject 的编码类型,是 Redis 内部实现各种数据类型所用的数据结构,每一种数据类型,可以对应不同的底层数据结构来实现(SDS/ziplist/intset/hashtable/skiplist等)。占用4bit
    lru:redisObject 的 LRU 时间。占用24bit
    refcount:redisObject 的引用计数。占用4个字节
    ptr:指向值的指针。占用8个字节。

redis的rehash:
redis有两张表,用户rehash的时候交替保存数据。一张表用于接收服务请求,另一张表用于rehash迁移表。
触发rehash条件:
负载因子:hash承载元素/当前设定的大小 >1 的时候会rehash;但是在持久化时不rehash
rehash之后扩容多大:和hashmap一样,扩大两倍。
渐进rehash:把很大的数据迁移工作,分摊到多次小的操作中。
● 增删改查哈希表时:每次迁移 1 个哈希桶
● 定时 rehash:如果 dict 一直没有操作,无法渐进式迁移数据,那主线程会默认每间隔 100ms 执行一次迁移操作。这里一次会以 100 个桶为基本单位迁移数据,并限制如果一次操作耗时超时 1ms 就结束本次任务,待下次再次触发迁移
(8)hashmap的扩容
扩容条件:
元素的数量达到总数*负载因子的时候会扩容
某个桶里链表长度大于8且总元素数小于64。或者说 shu
new一个hashmap第一次往里面加元素的时候(默认扩到16)。
为了保证容量是2的幂次,每次会扩大到原来的两倍。

扩容的时候会做三件事情:
JDK1.7 的时候会重新计算hash,用头插法插入新链表,链表顺序会倒置。
JDK1.8 之后:
第一、如果桶里只有一个元素,直接rehash。
第二、如果桶子里是链表或者红黑树,则需要划分成low(低位)和high(高位)两部分,划分的依据就是hashcode & oldcap(旧容量)0,如果等于0,则为low部分,位置不动,如果不等于0,则新的索引位置就是旧索引+旧数组长度。
第三,如果红黑树被划分之后,元素个数小于6个,会退化为链表(红黑树TreeNode里面继承了Node,有pre属性可以退化为链表)。
(9)hashmap和hashtable的key可以为null值吗?
答:
hashmap的key可以为null值。原因是底层计算hashcode的时候会特殊处理,null的hash值就是0,但是只能有一个,因为俩null值没法区分。
hashtable的key不能为null值,原因是底层没用hashcode,不能处理null,更重要的是它是线程安全的,如果key是null就不知道是存在null?还是这个key本来就是null。
(10)为什么负载因子是0.75?
1、如果设置成1,那么只有满了的情况下才会扩容,最好的情况就是16个元素分别不同的桶位置,否则hash碰撞概率会大大增加,查找速率会变慢。
2、负载因子太大会hash冲突,太小又会造成资源浪费,官方权衡之下进行了数学推理,发现0.7左右非常合适,但是容量是2的n次幂,那么取0.75正好可以把扩容阈值设为整数。
(11)初始容量的选择
期望插入的数据量n,计算n/0.75 +1,然后向上找到大于它最小的2次幂即可。
(12)JDK1.8 hashmap发生了什么变化?
1、解决hash冲突,链表变成红黑树
2、Entry变成Node,且Node节点hash类型是final
3、hash表计算索引的方法由异或运算变成与运算,并且加入了hash扰动
4、扩容算法发生变化,transfer移动到了resize里面
5、扩容算法由头插法变成尾插法。
(13)如何解决hash冲突
链地址法:冲突的元素存在链表里
开放地址法:线性探测,例如ThreadLocalMap(一直往后找空位)、二次探测再散列法(i±1、i±3的找),双重哈希(先算一个hash值p1,如果冲突了就用p1再哈希得到p2...,直到不冲突)
再hash法:用多个不同的哈希函数,第一个发生冲突就用第二个...直到无冲突
建立公共溢出区:把哈希表分为基本表和溢出表,发生冲突的放到溢出表。
(14)如何理解多态?
答:同一个操作作用于不同的对象可以产生不同的结果。(例如:调用run方法(同一个操作),A.run(),B.run()执行完的结果不同)
多态实现有三个条件:
1、实现接口或者继承父类
2、重写方法、
3、父类的引用指向子类对象。
多态是一种运行期的概念,它是根据代码运行实时决策出来的,让代码更灵活。维基百科上说多态分为静态多态和动态多态,有人认为函数的重载就是一种静态多态,但我不这么认为。
重载是同名不同参的方法,编译期间会根据参数类型来决定调用哪个方法。
重写是子类重写父类的方法。
重载是编译期绑定,写代码的就能根据具体参数决定调用。重写是运行期绑定,会根据父类引用具体指向的子类对象来决定调用哪个方法。
(15)final、finally、finalize区别
答:只是长得像,实际没什么关系
final:修饰变量,则不可变,修饰方法,则不可重写,修饰类,则不可被继承
finally:用于异常处理,程序抛异常后finally代码块的内容一定会执行,用于释放资源,比如连接对象,锁,threadLocal。除非JVM进程退出、线程执行过程中抛了Error异常。
finalize:用于在GC之前清理资源
(16)
和equals的区别
:对于基本数据类型,比较的是值相等。对于引用数据类型,比较的是内存地址是否相等。
equals:对于原始的Object类中的equals方法,底层也是调用
,但是后续的类重写了equals方法,例如String类的equals方法,首先比较两个变量指向的内存地址是否相等,也就是调用==,其次会判断二者的类型是否相等,最后再判断内容是否相等。
(17)equals与hashcode:
hashcode是Object中的方法,所以所有类都有hashcode方法。对于set集合而言,它不可重复,那么我们在插入元素的时候就需要判断元素是否已经存在,但是如果元素过多的话,一直调用equals判断会非常麻烦,所以集合就会重写hashcode方法来通过hashcode方法进行一系列计算拿到元素在集合中的索引位置,如果这个位置有元素,则需要使用equals方法来比较二者是否相等,这样就省去很多调用equals方法。
(18)为什么要重写equals方法和hashcode方法?
对象相等 等价于 equals方法的结果相等。hashcode相等是对象相等的必要条件。
重写equals方法:原始的equals方法只是比较基本类型的数值和引用对象指向的地址是否相等,我们需要比较内容是否相等,所以需要重新equals。
但是如果只重写equals方法,每次都需要比较地址、类型、内容这样效率就很低。所以需要一个高效的先行比较方法。
重写hashcode方法:
1、在向set集合这种不重复的集合中插入数据的时候,如果只使用equals来遍历判断效率很低,我们需要根据对象自身计算一个hashcode来计算出它在set集合中的索引位置,便于我们比较。
2、原始的hashcode方法是通过对象的地址来计算hashcode值,会导致equals相等的对象hashcode不相等,所以需要重写来保证数据的一致性。
所以我们判断对象是否相等的时候会先用必要条件hashcode相等,然后再用充要条件判断。
常见的hashcode方法:
String计算hashcode:首先判断成员变量hash是否为0,如果为0,且String长度不为0则计算hashcode。
判断是latin1编码还是UTF16编码,调用的hashcode方法不同。
字节数组的hashcode:将数组长度右移一位(相当于除以2,一位UTF16存储字节占2字节)。然后for循环(数组长度一半)里计算h=31h+getChar(两个字节转化为一个字符)。
为什么是31:第一、31是素数,可以减少哈希碰撞;第二、31
i可以通过位运算实现:(i<<5)-1
Object类型数组的hashcode:和字节数组类似。先判断是否为null,是,则返回0;再遍历对象
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
element的hashcode:它是一个本地方法,具体就是根据对象的地址值计算hashcode。
4、java异常
答:受检异常 & 非受检异常
受检异常:方法声明的时候证实了可能会有异常,代码编译的过程中必须显式处理否则编译报错,比如捕捉或者向上抛出。
例如:除了运行时异常和派生的子类、Error,其余基本都是。
非受检异常:一般是运行时异常类和他的子类,是代码逻辑问题,不用显示捕捉。
java异常家族:
Throwable(最顶级的异常类):包括Error和Exception
Error:系统或者硬件级别的错误,没法处理,只能退出程序。包括:虚拟机错误、线程死锁
常见的Error:OutOfMemoryError(爆内存)、StackOverFlowError、NoClassDefFoundError(编译器存在,但是运行期找不到类,例如类路径缺失,启动时漏掉了该类的JAR和目录,或者打包时没把依赖打进去,或者打进去之后被同名文件覆盖了)、InternalError(线程调度异常,属于JVM内部异常)、AssertionError(断言异常)
Exception:包括受检异常和非受检异常(运行时异常)
受检异常:文件异常、SQL异常、IOException(IO异常),编译期间必须显式处理。
非受检异常:主要是运行时异常及其子类,运行时异常不用throws,包括:数组索引越界、空指针、算数异常、唯一索引约束重复异常(插入数据时发生,也可做幂等)、类型转换异常、非法参数异常(IllegalArgumentException,例如枚举类使用valueOf()对参数进行校验)

try catch:运行时异常不用throws必须要catch,catch的顺序是先catch子类
异常处理模式:向上抛,抛给调用者、try catch,在catch代码块里处理。
5、枚举的特点、好处
特点:表示一组常量
好处:
枚举类的valueOf()方法可以校验参数
每个常量都可以定义一个方法,相比普通方法更灵活
天生是一个单例
枚举类是线程安全的,因为枚举类中的字段反编译后都是static final修饰的,而static字段在类加载的过程中就被初始化,且loadclass方法是线程安全的。
6、值传递、引用传递||深拷贝、浅拷贝
答:
值传递:调用函数的时候复制了一份值传递进去,不会影响原来的值。
引用传递:传递是对象引用,会改变原来的对象属性。
浅拷贝:创建一个新对象,对象属性中基本数据类型会拷贝值,引用数据类型会拷贝引用。
深拷贝:与浅拷贝不同的是,引用数据类型指向的对象也会进一步拷贝一个新的对象。
7、UUID
答:生成一个128位的二进制数,对同一时空中所有机器都唯一。
java用的是V3、V4
namespaceUUID V3:基于名称和名称空间生成MD5,保证同一名称空间不同名称不同,同一名称空间相同名称一定相同。
randomUUID V4:基于随机数的UUID
缺点:很长、可读性差。
(18)泛型
答:泛型就是将参数的类型进行参数化,调用方法需要传入具体的参数类
型。泛型是通过类型擦除实现的。所以泛型是工作在编译阶段的。
泛型擦除:在编译期间尽可能检查处错误,在编译的时候会把泛型给去除,生成的字节码文件里面没有泛型信息。
好处:
提升参数的复用性:List、List 只需要写一个List 即可
安全:Object类型转换是在运行时进行才检查的,如果转换错误程序直接挂了,泛型可以在编译的时候起到一个约束作用
8、反射
获取class对象的方法:
//通过具体的类去拿class文件
Class A= a.class;
//通过全路径
Class A = Class.forName("cn.java.a");
//通过对象实例去拿
Class A = a.getClass();
//通过类加载器拿,但是这样拿到的class不会初始化,静态资源不会执行
ClassLoader.getSystemClassLoader.loadClass("cn.java.a");
反射就是通过class对象获取类的属性、方法与构造函数:
常用方法:
.newInstance();
.getConstructors();
.getDeclearedConstructors();
getFiled();
getFileds();
getDeclearedFields();
getMethod();
getDeclaredMethod();
// 如果对私有属性处理就需要设置可达性为true
.setAccessible(true);
package cn.javaguide;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
/**
* 获取 TargetObject 类的 Class 对象并且创建 TargetObject 类实例
*/

    <?> targetClass = Class.forName("cn.javaguide.TargetObject");TargetObject targetObject = (TargetObject) targetClass.newInstance();/*** 获取 TargetObject 类中定义的所有方法*/Method[] methods = targetClass.getDeclaredMethods();for (Method method : methods) {System.out.println(method.getName());}/*** 获取指定方法并调用*/Method publicMethod = targetClass.getDeclaredMethod("publicMethod",String.class);publicMethod.invoke(targetObject, "JavaGuide");/*** 获取指定参数并对参数进行修改*/Field field = targetClass.getDeclaredField("value");//为了对类中的参数进行修改我们取消安全检查field.setAccessible(true);field.set(targetObject, "JavaGuide");/*** 调用 private 方法*/Method privateMethod = targetClass.getDeclaredMethod("privateMethod");//为了调用private方法我们取消安全检查privateMethod.setAccessible(true);privateMethod.invoke(targetObject);
}

}
答:反射就是通过Class对象拿到对应类的所有信息,包括类名、成员变量、成员方法、构造函数。反射是工作在运行时阶段的
反射会导致程序变慢:
1、反射涉及到动态解析,无法执行虚拟机优化、
2、反射的时候会将对象包装到Object[],要使用的时候又要拆包,转化成真实对象,对象一多就会GC,GC会导致程序变慢
3、调用方法的时候需要在方法数组中遍历寻找,还要检查可见性,比较慢。
反射会破坏单例:
单例主要是将构造函数私有化,不让外部访问构造函数去构造多个实例。
但是反射可以拿到构造方法,并且修改权限为可访问,然后拿构造方法创建实例。
可以避免这种情况,方法就是构造函数里面判断单例是否不为空(双重判定-DCL),不为空则说明已经存在了,就可以抛异常。
相同的操作还有反序列化
9、注解
注解是一个特殊接口,注解的实现逻辑在注解处理器完成。
定义一个注解:
priority和description是注解的属性,定义的时候可以给默认值。
// 注解的作用目标:方法
@Target(ElementType.METHOD)
// 注解的保留策略:运行时可见
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
// 注解元素,默认值为 1
int priority() default 1;
// 注解元素,默认值为空字符串
String description() default "";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface a{
int n() default 1;
int b() default 2;
}
注解的使用:
注解的属性一般是为方法提供了额外的元数据信息,可以在编译时或者运行时被读取。
例如@order注解就可以在属性值里面给整数来规定方法的执行顺序。
import java.lang.reflect.Method;

public class AnnotationProcessor {
public static void main(String[] args) throws NoSuchMethodException {
MyClass myClass = new MyClass();

    // 获取 importantMethod 方法Method importantMethod = MyClass.class.getMethod("importantMethod");// 检查方法上是否存在 MyAnnotation 注解if (importantMethod.isAnnotationPresent(MyAnnotation.class)) {// 获取注解实例MyAnnotation annotation = importantMethod.getAnnotation(MyAnnotation.class);System.out.println("方法名: " + importantMethod.getName());System.out.println("优先级: " + annotation.priority());System.out.println("描述: " + annotation.description());// 调用方法try {importantMethod.invoke(myClass);} catch (Exception e) {e.printStackTrace();}}// 获取 normalMethod 方法Method normalMethod = MyClass.class.getMethod("normalMethod");if (normalMethod.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation annotation = normalMethod.getAnnotation(MyAnnotation.class);System.out.println("方法名: " + normalMethod.getName());System.out.println("优先级: " + annotation.priority());System.out.println("描述: " + annotation.description());try {normalMethod.invoke(myClass);} catch (Exception e) {e.printStackTrace();}}
}

}
10、@Value注解进行属性注入
@value注解可以根据属性占位符里的变量名称从配置文件里面读取属性值并注入。
可以注入字符串、数字、布尔值、数组、列表、Map
@value(${app.name}),属性占位符是配置文件中的值。
@value("#{'${app.name}'.split(',')}")
public List app;

@value("#{'${app.name}'}")
Map<String,String> map;
app={key1:value1,key2:value2};
11、 类的加载过程:
类的加载过程:
加载->链接->初始化
加载:通过类加载器加载类的二进制字节流byte[]到JVM堆内存中生成Class对象。
验证:文件格式验证、元数据验证、字节码验证、符号引用验证
准备:为静态变量分配内存
解析:将符号引用(一组字面量,用符号表示引用对象,一个java文件编译成class文件的时候类的地址用符号引用替代)转换为直接引用(目标对象的地址或者间接指向对象地址的一个句柄),实际上有一部分工作留到运行期进行解析(多态的解析)
初始化:执行clinit()方法,它是线程安全的。为静态变量赋初始值。
类加载器:
启动类加载器->标准拓展类加载器->应用程序类加载器。+自定义类加载器
BootStrap ClassLoader
Extension Classloader
Application ClassLoader
User ClassLoader
它们是层级关系,但不是继承关系
启动类加载器:加载java_home/lib下的jar包
标准拓展类加载器:加载java_home/lib/ext/下 的jar包
应用程序类加载器:加载系统路径下的类库
双亲委派机制:
一个类加载器收到加载类的请求,首先不会自己加载,先看有没有被加载过,如果没有则委派给它的上一级加载器加载,上一级加载器再委派给上一级,只有上级加载器加载不了才返给下级加载器加载。
任何一个类加载任务到来,先检查是否被加载(findloadclass()方法),如果没有就查看parent是否为空,如果不为空就调用parent的loadclass()方法来加载类。
好处:
保证类的唯一性,而且不被重复加载(因为加载的时候会看是否加载过)
保证程序安全性,不会被篡改。
如何打破:
自己写一个类继承ClassLoader并重写loadclass方法,例如TomCat。如果类是自动注入的,则需要在SpringApplication.run() 方法之前将Thread.ContextClassLoader中的类加载器设置为自定义的加载器,在自定义的类加载器中,if判断待加载的类非null,且类名称是目标类的名称,然后先自己加载,如果不是则使用parent上级加载器进行加载。
类加载器:
JDK1.8:

JDK1.9之后,拓展类加载器被重命名为平台类加载器PlatformClassLoader,负责加载JDK平台本身的类库,位于JDK/lib目录下
12、权修饰符

default是给本包访问的,protected是给子类访问的
子类和父类可能在同一个包也可能不在同一个包,所以子类的范围更大。
13、Tomcat
启动流程:init、load、start
最大线程数:200,最小空闲线程数:10
Tomcat的作用:
作为Web服务器:可以处理静态资源(HTML、CSS等静态资源),负责字节流与HTTPRequest对象之间的转化。
作为Servelet容器:管理Servelet的生命周期
客户端发起请求:根据URL构建HTTP请求,通过TCP/IP协议发送给对应的服务器的端口(例如Tomcat)
Tomcat接收请求:连接器Conector接收客户端的HTTP请求,并将字节流转化成HTTPServeletRequest对象(包含请求头、请求体)。
请求的映射与转发:Servelet容器捕获请求之后,传递给DispatcherServelet,DispatcherServelet根据路由规则转发给对应的Controller。
Controller处理:执行业务逻辑,将响应结果返回给DispatcherServelet,然后DispatcherServelet将响应结果写入HTTPServeletRequest对象。
Tomcat封装并返回:然后将HTTPServeletRequest封装成HTTP响应返回。
Tomcat打破双亲委派机制:
因为Tomcat可以运行多个应用,不同应用依赖包的版本可能不一样,如果使用双亲委派机制无法加载同一个类的不同版本,所以为了具有隔离性,每一个应用都会有一个自己的WebAppClassLoader加载类,对于版本相同的类,就用SharedClassLoader加载。
delegate=false就会打破双亲委派机制

14、Comparator比较器:
list.sort((a,b)->a-b) 相当于
list.sort(new Comparator(){
public int compare(Integer o1,Integer o2){
return o1-o2;
})
Comaparable接口:
可以自定义类,然后实现comparable接口,重写compareTo方法
需要实现compareTo方法,Integer、Double、String都实现了comparable接口,可以直接调用conpareTo方法:返回值小于0,则当前对象小于传入的对象。
return num1.conpareTo(num2)
15、BIO、AIO、NIO模型
BIO:同步阻塞模型。
NIO:同步非阻塞模型,线程发起请求后直接返回,无需阻塞,后续轮询IO缓冲区即可。
AIO:异步非阻塞模型,与NIO的区别在于无需轮询,而是IO准备好执行回调函数通知。
同步非阻塞的IO模型,核心三要素:通道、缓冲区、Selector
初始化
○ 创建Selector对象,它是 NIO 的核心组件,用于监听多个Channel上的事件。例如:Selector selector = Selector.open();
○ 创建Channel通道,常见的通道类型有SocketChannel(用于 TCP 网络通信)、ServerSocketChannel(用于监听 TCP 连接)等。以SocketChannel为例:SocketChannel channel = SocketChannel.open();
○ 创建Buffer缓冲区,根据数据类型的不同,有ByteBuffer、CharBuffer等多种类型。如:ByteBuffer buffer = ByteBuffer.allocate(1024);
注册通道到选择
○ 将Channel配置为非阻塞模式,因为 NIO 是基于非阻塞的 I/O 操作。对于SocketChannel:channel.configureBlocking(false);
○ 将Channel注册到Selector上,并指定需要监听的事件。事件类型包括连接事件(SelectionKey.OP_CONNECT)、读事件(SelectionKey.OP_READ)、写事件(SelectionKey.OP_WRITE)等。例如,注册读事件:channel.register(selector, SelectionKey.OP_READ);
监听事件
使用Selector的select()方法监听注册通道上的事件。该方法会阻塞,直到有事件发生,返回发生事件的通道数量。例如:int readyChannels = selector.select();
当select()方法返回大于 0 的值时,表示有事件发生,可以通过selector.selectedKeys()获取发生事件的SelectionKey集合。Set selectedKeys = selector.selectedKeys();
处理事件
○ 遍历selectedKeys集合,针对不同类型的事件进行相应处理。
○ 读事件处理:当通道有可读数据时,将数据从Channel读取到Buffer中。例如:文件读取的时候会先把数据放到buffer里面,然后从buffer到channel。再或者网络通信的时候TCP对应的socketchannel也是先把数据从通道放到buffer里,然后在由线程读取,进行处理。
○ int bytesRead = channel.read(buffer);,读取数据后,可能需要对Buffer中的数据进行处理,如解析、转换等。处理完数据后,需要根据情况清空或调整Buffer的状态,以便下次使用,如buffer.clear();或buffer.flip();
○ 写事件处理:如果是写事件,将Buffer中的数据写入到Channel。例如:int bytesWritten = channel.write(buffer);,同样在写入后,根据需求调整Buffer状态。
○ 连接事件处理:当连接事件发生时(OP_CONNECT),完成连接操作或处理连接相关逻辑。比如在客户端连接服务器时,检查连接是否成功:if (channel.isConnectionPending()) { channel.finishConnect(); }
关闭资源
○ 在操作完成后,需要关闭Channel和Selector等资源,以释放系统资源。例如:channel.close(); selector.close();

16、单例和多例
单例与多例的区别是一个类的实例数量。但是他们都不对外提供构造方法。通过@Scope注解控制对象单例(Singleton)/多例(Prototype)。
使用规则:当对象含有可变状态时(实际应用中状态可变),则使用多例,否则单例。
单例应用场景:数据库、redis的连接对象、IOC容器。
多例应用场景:线程池创建线程、或者数据库的连接池。
使用单例是基于享元设计模式,避免每次请求都创建一个新对象,减少内存占用;使用多例是避免出现线程安全问题。
17、重写和重载
重载:编译期概念,它指的是多个方法的名称相同,但参数列表、返回值和权限修饰符都可以不同。编译器通过参数列表来判定重载的具体方法。
重写:运行期概念,它指的是子类继承父类重写父类的方法,方法名和参数列表必须相同,权限修饰符不能比父类的严格,返回值类型可以是父类返回值类型,也可以是其子类。
18、java对象头的组成
19、Java对象头
我们以Hotspot虚拟机为例,Hotspot的对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)。
Mark Word:默认存储对象的HashCode,分代年龄和锁标志位信息。这些信息都是与对象自身定义无关的数据,所以Mark Word被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的数据。它会根据对象的状态复用自己的存储空间,也就是说在运行期间Mark Word里存储的数据会随着锁标志位的变化而变化。
Klass Point:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

20、Java集合框架
单列集合:Collection接口:List接口,ArrayList、LinkedList、Vector;Set接口,HashSet、TreeSet;
双列集合:Map接口:HashMap,Hash Table,ConcurrentHashMap
21、接口与抽象类的区别:
方法定义:
接口里面只有抽象方法,java 8之后有默认方法,抽象类里面都有。抽象类里面可以有普通成员变量,但是接口里面只能有常量。
实例化的角度:
二者都不能实例化,但是抽象类里面有构造方法,但是不能使用构造方法实例化,构造方法一般用于初始化变量。
设计模式的角度:
接口是一种规范,我们对外提供的是接口,也称为面向接口编程。抽象类是抽取出多个实现类的共用逻辑,复用代码,例如模板方法

相关文章:

Java笔记

String、StringBuilder、StringBuffer String不可变,StringBuilder和StringBuffer可变,只有StringBuffer是线程安全的。 String不可变的四个原因: (1)类被final修饰不可被继承 (2)底层char[]数组被final修饰 (3)提供的方法返回值都是new一个新String对象 (4)字符串常…...

分布式 笔记

1、分布式锁的实现方式: 1、数据库 基于数据库表: 创建一张锁表:id、方法名称(唯一索引)、备注信息、参数信息(对应重载方法)、更新时间 锁住一个方法等价于往锁表里插入一行数据,通过方法名称字段的唯一性把其他想获得方法的线程给校验住 缺点:数据库挂了就很麻烦,需…...

Windows Server 2019 中文版、英文版下载 (2025 年 9 月更新)

Windows Server 2019 中文版、英文版下载 (2025 年 9 月更新)Windows Server 2019 中文版、英文版下载 (2025 年 9 月更新) Windows Server 2019 x64 Version 1809 (updated Sep 2025) 请访问原文链接:https://sysin.org/blog/windows-server-2019/ 查看最新版。原创作品,转载…...

Windows Server 2016 中文版、英文版下载 (2025 年 9 月更新)

Windows Server 2016 中文版、英文版下载 (2025 年 9 月更新)Windows Server 2016 中文版、英文版下载 (2025 年 9 月更新) Windows Server 2016 x64 Version 1607 (updated Sep 2025) 请访问原文链接:https://sysin.org/blog/windows-server-2016/ 查看最新版。原创作品,转载…...

Windows Server 2025 中文版、英文版下载 (2025 年 9 月更新)

Windows Server 2025 中文版、英文版下载 (2025 年 9 月更新)Windows Server 2025 中文版、英文版下载 (2025 年 9 月更新) Windows Server 2025 LTSC x64 (updated Sep 2025) 请访问原文链接:https://sysin.org/blog/windows-server-2025/ 查看最新版。原创作品,转载请保留出…...

美联储降息 25 个基点,这事儿跟我们有多大关系?

正文今天聊个有时效性的东西,美联储降息。25 个点。17 号晚上公布的。当然那个时候我还在睡觉,我虽然关心美联储,但是不至于连夜追。身体健康还是比 FED 啊、鲍威尔啥的重要多了。有些人可能会觉得这个事儿挺遥远的。但其实并不是。想想我们银行利率降到这么低就懂了。现在银…...

Windows Server 2022 中文版、英文版下载 (2025 年 9 月更新)

Windows Server 2022 中文版、英文版下载 (2025 年 9 月更新)Windows Server 2022 中文版、英文版下载 (2025 年 9 月更新) Windows Server 2022 x64, Version 21H2 (updated Sep 2025) 请访问原文链接:https://sysin.org/blog/windows-server-2022/ 查看最新版。原创作品,转…...

袋鼠云跻身榜单2025中国Data+AI创新企业榜Top15,入选“2025中国隐形独角兽500强”榜单等多项荣誉

一、袋鼠云跻身榜单2025中国Data+AI创新企业榜Top15、2025中国垂直AI Agent创新企业榜TOP30为响应AI产业“技术深化+规模落地”的关键进阶期,国内IT市场研究与咨询机构「第一新声」正式启动了第三届【AI创新先锋—2025中国AI产业创新先锋榜单】评选活动,旨在发掘并表彰受资本…...

k8s系列--前世今生

基础设施即服务 阿里云,国外IWS 平台即服务 新浪云 --docker成为了平台即服务的下一代标准 软件设施即服务 office 为什么需要K8s,传统的架构不需要k8s,但是引入docker容器化技术以后,容器内部的访问变得复杂了,容器的集群化,有没有好的产品,有需求就有产品 Apache MESOS…...

excel文本改为数据格式

excel文本改为数据格式原理和方法转自:https://zhuanlan.zhihu.com/p/179945111 1)选中列(不能有合并的列)---数据----分列-----完成。 2)选中多列,必须是有绿三角形的开始----------电机加圈的i------------------转换为数字...

面向对象初步接触-学生信息管理系统

1. 功能讲解 1.1 数据处理该程序主要处理学生数据,包含学生的name、age、gender、id、major、gpa这些基本信息。 学生数据存储在StudentManagementSystem类的students成员变量中,每个学生的具体信息封装在Student类的对象中,这些对象被添加到List集合中统一管理。 不同之处:…...

Numpy高维数组的索引()

# 创建一个形状为 (3, 4, 2) 的随机数组 # arr 代表 3 个实例,每个实力有 4 个任务点,每个任务点有 (x, y) 坐标 arr = np.random.randint(0, 10, size=(3, 4, 2))arr:[[[8 4][2 9][0 5][4 7]][[5 5][1 6][8 5][1 8]][[6 2][5 5][4 5][9 6]]]索引或切片 描述 这里的ijk都要加…...

详细介绍:jQuery 操作指南:从 DOM 操作到 AJAX

详细介绍:jQuery 操作指南:从 DOM 操作到 AJAXpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace …...

一个 Blazor/WinForm 开发者的 WPF 学习记:通往 Avalonia 的那条路

一个 Blazor/WinForm 开发者的 WPF 学习记:通往 Avalonia 的那条路 写在前面 做了几年 Blazor 和 WinForm,本来以为桌面端这件事就这么过去了。直到我认真考虑跨平台桌面方案,才发现绕不开 Avalonia。而要真正用好 Avalonia,最好先补 WPF 这一课。这篇文章不是教程,更多是…...

VulkanAPI细节梳理2

// --- 创建渲染通行证(支持多视图和深度缓冲) ---std::vector<VkAttachmentDescription> attachments(2);// 颜色附件attachments[0].format = format;attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;attachme…...

React 状态丢失:组件 key 用错引发的渲染异常 - 指南

React 状态丢失:组件 key 用错引发的渲染异常 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monos…...

快速实现 Excel 表格转 SVG:Java 教程 - E

如果你曾尝试过把 Excel 表格导出为 SVG 图片,就会发现 Excel 本身并不支持这种格式。虽然市面上存在一些在线转换工具,但上传文件存在效率与安全方面的顾虑。对于开发者来说,使用 Java 来实现 Excel 到 SVG 的转换,是一种更灵活、可控的方式。本文将演示如何通过简单的 Ja…...

绕过文件上传限制实现客户端路径遍历漏洞利用的技术解析

本文详细解析了如何通过精心构造JSON文件绕过PDF和图像上传验证机制,利用mmmagic、pdflib和file命令的检测特性实现客户端路径遍历攻击的技术方法与实战案例。绕过文件上传限制实现客户端路径遍历漏洞利用 在我之前的博客文章中,我演示了如何利用JSON文件作为客户端路径遍历(…...

事件总线之初步学习

第一步:创建一个eventBus.js 文件名可根据个人爱好取名即可; 内容:import Vue from vue const eventBus = new Vue(); export default eventBus;第二步:使用import EventBus from @/common/eventBus;//监听全局事件clear-login-interval EventBus.$on(clear-login-interva…...

Markdown Day04

常用DOS命令 ##查看当前目录下所有文件dir ##切换目录cd change directory ##cd..回到上一个 ##清理屏幕cls ##退出exit ##查看电脑IP,ipconfig ##打开应用 calc notepad mspaint ##ping 命令 ping www.baidu.com ##文件操作 ad 创建目录 cd> 新增文件 del 删除文件 rd 移…...

C++中类的内存存储

目录类类对象的非虚成员函数类的成员变量空类对象具有虚函数的类对象 类 类本身不会存储在内存中,类实例化的对象才会保存在内存中。但是使用 sizeof 计算类大小时能得到结果,这是因为 sizeof 会在编译时就得到类型信息,这只与类的布局有关。 类对象的非虚成员函数 考虑如下…...

PyTorch 优化器(Optimizer)

优化器(Optimizer)是深度学习训练过程中用于更新模型参数的核心组件。在训练神经网络时,我们需要通过反向传播计算损失函数相对于模型参数的梯度,然后使用优化器根据这些梯度来更新参数,以最小化损失函数。PyTorch 优化器(Optimizer)技术指南 目录优化器概念 常用优化器…...

实用指南:域名市场中,如何确认域名的价值

实用指南:域名市场中,如何确认域名的价值pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !impo…...

初步了解Neo4j

1. 是什么? Neo4j 是一个原生图数据库。它与我们熟悉的关系型数据库(如 MySQL, PostgreSQL)和 NoSQL 数据库(如 MongoDB)有根本性的不同,因为它专门为存储和查询数据之间的关系而设计。 它的核心哲学是:“关系即一等公民”。这意味着关系(或连接)和数据本身同等重要,…...

多模态和语音 AI 年度收官大会,把握 2026 技术风向标!

如果今年只参加一场多模态和语音 AI 大会,来 Convo AI & RTE2025 就够了。你是否好奇:1⃣从端到端语音模型和全双工技术,未来音频还将有哪些突破方向?2⃣如何挖掘端侧 AI 潜能,定义下一代智能硬件终端?3⃣从主动智能体到可交互世界模型,实时多模态 AI 将驱动怎样的未…...

做题

P4159 [SCOI2009] 迷路 矩阵快速幂优化递推。 首先最暴力的想法,设 $ f_{i,j} $ 在 $ j $ 时刻,到达点 $ i $ 的种类数。 枚举时间和 $ i $,然后 $ f_{i,j} = \sum\limits_{k=1}^n {f_{k,j-w[i][k]}} $。 时间很大,所以肯定行不通。 这样显然是不能用矩阵来优化的。 考虑拆…...

解码C语言函数

一、函数基本概念 1.1 函数定义 概念:把一个功能的实现流程封装起来,使用户留下接口进行调用 作用:参数创建该功能进行封装操作,返回值即通过功能显示的产出 1.2 函数组成要素返回值类型:根据函数功能而定,需要在函数头中指定子程序类的返回值类型 参数名:在函数体中提取…...

SchemaStore

Hello World本文来自博客园,作者:南宫影,转载请注明原文链接:https://www.cnblogs.com/nangongying/p/19100468...

XSS攻击防御

目录背景和价值为什么需要输出编码?不同场景下的编码方式(白话版)1. 最常见场景:内容显示在HTML标签里(比如<div>、<span>中)2. 特殊场景:内容显示在HTML标签的属性里(比如value、href中)3. 特殊场景:内容要在JavaScript代码里使用4. 特殊场景:内容作为…...

imes开发部署

一.git地址下载源码 二.后端设置 1.增加配置文件:ktg-admin/src/main/resources/application-test.yml2.临时修改代码:ktg-mes/src/main/java/com/ktg/mes/task/MesTask.java,如图注释2行。 3.快捷键Ctrl+Alt+Shift+S,打开项目结构(Project Structure)对话框4.编辑配置5…...

思维题做题记录-1

CF2600左右有趣的思维题做题记录-1 CF1458C. Latin Square 考虑将原矩阵写成 \(n\times n\) 个限制形如 \((i,j,a_{i,j})\),那么所有操作就是对这些限制进行的修改:对于 UD 操作相当于将限制改为 \((i\mp 1,j,a_{i,j})\)。 对于 LR 操作相当于将限制改为 \((i,j\mp 1,a_{i,j}…...

如何在极短时间内通透一个大型开源项目

如何在极短时间内通透一个大型开源项目前言 在现代软件开发中,快速理解和掌握大型开源项目是一项至关重要的技能。无论是参与开源贡献、技术选型,还是学习先进架构模式,都需要我们具备高效解读项目的能力。本文将以 OpenDeepWiki 项目为例,深入剖析如何运用AI技术快速通透一…...

求 Ray Ping - Gon

rt(跟风...

LCT学习笔记

LCT学习笔记从例题开始: P3690 【模板】动态树(LCT) 对于一棵静态的树,常见方法是树剖然后走链,但是在动态的情况下常见的重链或长链就会很慢,因为修改连边情况后就不满足性质了 引入一个新的方法:实链剖分,对于一个节点,任选一个儿子,连边为实边,其余为虚边,注意这…...

Visual Studio 2026 Insiders 重磅发布:AI 深度集成、性能飞跃、全新设计

近日,微软正式发布 Visual Studio 2026 Insiders!这是迄今为止 Visual StudioE 极具跨越式的一次升级。新版本不仅将 AI 深度融入开发工作流,还带来了企业级性能的显著提升,以及更轻盈、现代的界面设计,全面提升开发体验。近日,微软正式发布 Visual Studio 2026 Insiders…...

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-29- 操作单选和多选按钮 - 下篇(详细教程) - 北京

1.简介 我们可能会遇到一直测试单选和复选按钮的测试场景,如果就十几道选择题,那就手工点击,马上完事,但是如果是让你测试题库呢?那不得那鼠标点击冒烟了,手指点到抽筋了。尤其是做教育类的软件测试,这些就是家常便饭了。因此今天这一篇宏哥主要是讲解一下,如何使用Pla…...

自定义注解实现服务分处理-策略模式

路由:请求标识→匹配 Service→调用 process 方法 通过自定义注解 @BusinessServiceMapping 标记具体业务 Service,注解值(如 DC 代表客户、ORD 代表订单)与请求参数中的业务标识关联;再通过 Spring 容器扫描 + 策略模式,实现 “请求标识→匹配 Service→调用 process 方…...

iOS26正式版全新风格!一文汇总实用新功能!

苹果在9月17日凌晨正式推送了iOS26系统更新,这次版本更新带来了多达61项新功能与优化。经过9个Beta版和近100天的测试,iOS26正式版终于与用户见面,版本号为23A340,更新包大小约8GB。 iOS26不仅在设计语言上焕然一新,更在AI能力、交互体验和隐私保护等多个维度进行了全面升…...

远程控制应用的中的全球节点功能如何开启?插件类型、并发数量怎么选?

不知道大家使用远程控制应用进行跨系统跨设备操作主要都是针对哪些场景呐?其实对于很多需要跨境远程办公的人群或进行售后设备升级管理的朋友来说无疑是必不可少的,甚至于海外学子们来说同样也至关重要,毕竟总有需要协助国内亲友处理问题的时刻,代操作远高于语音指导的效率…...

借助Aspose.HTML控件,使用 Python 将 HTML 转换为 DOCX

Aspose.HTML for Python via .NET提供了用于自动执行文件格式转换任务的类和方法。此外,它能够精确地转换 HTML 结构和样式,是 Python 开发人员的理想选择。本教程将向开发者展示如何在 Python 中以编程方式将HTML转换为DOCX。我们将使用一个非常快速的 Python SDK 将网页转换…...

openEuler 24.03 (LTS-SP2)安装mysql 8.0.41

环境:OS:openEuler 24.03 (LTS-SP2)(安装时候没有图形界面的选择项可选)mysql:8.0.41 glib.2.17 操作系统下载https://www.openeuler.org/en/download/#openEuler%2024.03%20LTS%20SP2查看系统glibc版本[root@localhost soft]# ldd --versionldd (GNU libc) 2.38Copyright (C) …...

7.数据库归档异常检查与处理

备库: select instance_name,status from v$instance; select open_mode from v$database; @dgstat 如果都是00:00:00则说明本地从生产到DR同步没有问题 @dgpro 与上面的RFS的sequence#进行对比,可以算出生产与DR相差的sequence Block# 1分钟前是852100,1分钟后是856100,…...

Gitlab 关键字

核心原则:一切路径始于项目根目录:https://blog.csdn.net/qq_14829643/article/details/150773286include: local:中的所有路径都是相对于当前项目的根目录进行解析的。它既不是传统意义上的“绝对路径”(如 /etc/gitlab-runner/config.toml,这会指向 Runner 服务器的文件…...

8.listener日志占用过大处理方法

ps -ef |grep tns asmenv 查询listener.log的位置路径 lsnrctl status [listener name] 例如: listener log file : /oracle/TEST/diag/tnslsnr/xianigux/listener/alert/log.xml cd /oracle/TEST/diag/tnslsnr/xianigux/listener/alert 删除除了log.xml以外的所有xml文件 rm …...

马建仓AI助手完成全链路升级:三十余项新能力重塑研发工作流

马建仓AI助手完成全链路升级:三十余项新能力重塑研发工作流 在数字化转型浪潮席卷各行各业的当下,研发效率正成为企业竞争力的关键指标。马建仓AI助手近日宣布完成面向真实研发流程的全面升级,新增三十余项智能能力,覆盖需求、开发、测试、项目管理等关键环节,标志着企业级…...

线性回归与 Softmax 回归:深度学习基础模型解析 - 实践

线性回归与 Softmax 回归:深度学习基础模型解析 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", mon…...

浏览器下载,一定要开启这个隐藏功能!

大家好,我是 Immerse,一名独立开发者、内容创作者。关注公众号:沉浸式趣谈,获取最新文章(更多内容只在公众号更新) 个人网站:https://yaolifeng.com 也同步更新。 转载请在文章开头注明出处和版权信息。我会在这里分享关于编程、独立开发、AI干货、开源、个人思考等内容…...

开源项目进度管理系统 PJMan:让技术项目进度可视化、数据化的利器

在软件项目管理过程中,进度不透明、任务卡点难定位、人员效率难量化是许多技术团队面临的痛点。今天为大家介绍一款开源项目进度管理系统 ——PJMan,其「项目概览」页面通过分层可视化与数据驱动的设计,将项目的 “全局趋势、任务细节、人员效率” 全方位呈现,为技术团队提…...

【光照】[漫反射]UnityURP兰伯特能量守恒吗?

【从UnityURP开始探索游戏渲染】专栏-直达兰伯特漫反射的能量守恒性 ‌能量守恒基本原理‌ 在物理正确的渲染中,能量守恒要求:表面反射的光能总量 ≤ 入射光能 漫反射+高光反射 ≤ 1.0 没有能量凭空产生或消失‌经典兰伯特模型的能量守恒问题‌ 传统兰伯特漫反射公式: $漫反…...

Microsoft AI Genius 限时挑战赛:实战开启,等你应战!

通过 Microsoft AI Genius 系列 2.0 的实战专题课程,相信各位开发者对智能 GitHub Copilot 副驾驶 Agent Mode、Azure AI Foundry Agent Service(国际版)及 Copilot Studio 的理解与掌握达到了新高度。现在,是时候将所学理论转化为实际行动,投身真实场景检验成果了。 ↓↓…...