一、Java 核心基础与进阶

1、我们知道 Java 中存在 “值传递” 和 “引用传递” 的说法,你能结合具体例子,说明 Java 到底是值传递还是引用传递吗?这背后涉及到 JVM 中哪些内存区域的交互?

Java中只有值传递,不存在引用传递。判断传递方式的核心在于:传递的是变量的副本,而非变量本身。区别在于副本的内容是基本类型的值还是对象引用的地址。

案例1:传递基本类型(int)

public static void main(String[] args) {int a = 10;change(a);System.out.println(a); // 输出 10,未被修改
}
private static void change(int num) {num = 20; // 操作的是副本 num,与原变量 a 无关
}

在上述案例中,变量a是基本类型,在虚拟机栈的局部变量表中,传递时将a的值复制一份给参数num,二者在栈中是独立的内存空间,修改num不影响a。

案例2:传递引用类型

class User {String name;public User(String name) { this.name = name; }
}
public static void main(String[] args) {User user = new User("张三");changeUser(user);System.out.println(user.name); // 输出 "李四",被修改replaceUser(user);System.out.println(user.name); // 仍输出 "李四",未被替换
}
private static void changeUser(User u) {u.name = "李四"; // 操作副本 u 指向的堆中对象(与原 user 指向同一对象)
}
private static void replaceUser(User u) {u = new User("王五"); // 副本 u 指向新对象,与原 user 无关
}

在上述案例中,先是new了一个user对象,存储在虚拟机栈的局部变量表,指向堆内存中新建的user对象,调用changeUser方法时,传递的是user的副本,即堆中对象的地址,形参u与user指向同一堆对象,因此改变u.name会影响源对象,而调用replaceUser时,形参u被赋值为新对象的地址,但原user的地址未变,因此源对象不受影响。

2、HashMap 是日常开发中最常用的集合之一,你能详细说说 JDK 1.7 和 JDK 1.8 中 HashMap 的实现差异吗?比如哈希冲突解决方式、扩容机制、线程安全性问题,以及为什么 JDK 1.8 要将链表转红黑树的阈值设为 8?

hashmap的核心是“数组+链表/红黑树”的哈希表结构,jdk1.8针对性能问题做了大幅优化,具体差异是:

1)底层结构:jdk1.7使用的是数组+链表的头插法,jdk1.8使用的是数组+链表+红黑树的尾插法

2)哈希冲突解决:jdk1.7仅链表,使用的是拉链法,jdk1.8是当链表长度<=7时用链表,>8转红黑树。

3)扩容机制:jdk1.7扩容时重新计算所有元素哈希值,jdk1.8对于每个节点,根据哈希值与原容量的与运算结果,若结果为0,则节点位置不变,若结果不为0,则节点在新数组中的索引=原索引+原容量。

4)线程安全性:jdk1.7并发扩容时会出现“链表环”,可能导致死循环,而jdk1.8使用尾插法避免链表环,但仍非线程安全。

5)初始容量计算:jdk1.7构造时直接初始化数组,jdk1.8则延迟初始化,首次put时才创建数组。

那为什么链表转红黑树的阈值设为8呢?

1)从概率角度上讲,hashmap中链表长度遵循泊松分布,链表长度达到8的概念极低,说明此时哈希冲突已非常严重,链表查询效率会急剧下降。

2)从性能权衡的角度上讲,红黑树的插入和删除复杂度是O(logN),但维护红黑树的开销比链表大,若阈值设的太小,会频繁触发树化,增加开销,设的太大则链表查询耗时过长。

3)反向阈值:当链表长度因删除元素缩短至6时,红黑树会转回链表,避免因频繁波动导致反复树化或链化。

3、线程池是并发编程的核心组件,你在项目中是如何配置线程池参数的?请结合具体场景说明你的设计思路,以及如何避免线程池的常见问题?

线程池的核心参数主要包括:核心线程数(corePoolSize),最大线程数(maximumPoolSize),任务队列(workQueue),拒绝策略(rejectedExecutionHandle)等。

如何配置参数主要看业务场景,下面举两个例子:

1)复杂计算,排序类场景:此场景特点是任务主要消耗CPU资源,线程空闲时间极少,一般配置规则是 核心线程数=CPU核心数+1(这里+1是为了避免CPU空闲,若某个线程因页缺失等短暂阻塞,可立即有线程补位),最大线程数和核心线程数保持一致,避免创建临时线程,减少上下文切换导致的开销。

2)数据库查询,RPC调用,文件读写等场景:此场景特点是任务大部分时间都在等待IO完成,线程空闲时间长,一般配置规则是 核心线程数=2*CPU核心数,最大线程数可设为核心线程数的2~4倍。

任务队列的选择优先使用有界队列(ArrayBlockingQueue),避免用无界队列导致任务无限堆积,最终触发OOM。

有界队列(ArrayBlockingQueue):基于数组实现的有界阻塞队列,特点是容量固定,创建时必须指定大小,支持公平和非公平的访问策略,适用于任务数量已知,需要控制队列大小的场景。

无界队列(LinkedBlockingQueue):基于链表实现的阻塞队列,特点是可指定容量,默认容量为Integer的最大值,近似无界,吞吐量通常高于有界队列,适用于任务数量不确定,需要较大缓存空间的场景。

拒绝策略可从CallerRunsPolicy,DiscardOldestPolicy两者中选,核心业务,例如订单支付等可以使用CallerRunsPolicy,避免任务丢失,非核心业务,如日志收集,可使用DiscardOldestPolicy,丢弃最旧的的任务或者自定义策略,禁止使用AbortPolicy(默认,直接抛异常),会导致业务中断。

AbortPolicy(默认策略):当任务队列已满且线程池中的线程数达到最大线程数时,直接抛出RejectedExecutionException 异常

CallerRunsPolicy(调用者运行策略):让提交任务的线程自己执行该任务

DiscardPolicy(丢弃策略):直接丢弃新提交的任务,不做任何处理也不抛出异常

DiscardOldestPolicy(丢弃最旧任务策略):丢弃队列中最旧的任务,再次尝试提交新任务

如何避免线程泄露?

当任务执行时无限阻塞,导致线程长期被占用,无法回收的情况出现时,可以给任务设置超时时间,并使用有界队列+监控的方式,当队列超过阈值则告警,定期检测空闲线程,设置allowCoreThreadTimeOut为true让核心线程超时回收。

如何避免队列积压?

监控队列使用率,当超过80%时,自动扩容线程池(动态调整最大线程数)或降级非核心业务。

4、谈谈你对 Java 内存模型(JMM)的理解?它解决了什么问题?volatile 关键字的作用是什么?它能保证原子性吗?为什么?

JMM是一种抽象的模型,用来屏蔽各种硬件和操作系统的内存访问差异,java内存模型定义了线程和主内存之间的抽象关系,线程之间的共享变量存在主内存中,每一个线程都有一个私有的本地内存,本地内存存储了该线程以读写共享变量的副本。

JMM主要解决了多线程场景下因CPU缓存,指令重排导致的可见性,原子性,有序性等问题。

可见性:一个线程修改的变量,其他线程能立即看到

有序性:一个操作不可中断,要么全部执行,要么全部不执行

有序性:程序执行顺序与代码顺序一致

JMM通过内存屏障实现上述特性,禁止指令重排序,强制缓存刷新,确保线程间变量交互符合预期。

volatile的作用和局限性

volatile是轻量级同步机制,仅保证可见性和有序性,不保证原子性。

可见性是指当一个共享变量被线程更改,其他线程会立即感知到,这里的原理是因为当一个变量被volatile修饰后,线程获取时不会从自己的本地内存中取,而是直接去主内存中取,每次修改完后也会及时同步到主内存中。有序性是指,操作被volatile修饰后的变量,不会被重排序。

不保证原子性:

private volatile int i = 0;
// 多线程执行 increment(),最终结果可能小于 10000
public void increment() {i++; // 非原子操作,分“读 i -> i+1 -> 写回 i”三步
}

即使i时volatile,多线程同时读i时,可能都拿到相同的值,各自加1后写回主内存,最终结果为101,而非102。解决原子性需要用到synchronized 或 AtomicInteger(CAS 机制)。

5、垃圾回收(GC)是 JVM 性能优化的重点,你了解哪些常见的垃圾收集器?在项目中如何判断当前 GC 策略是否合理?如果出现 Full GC 频繁,你的排查步骤是什么?

常见的垃圾收集器:

Serial GC(串行收集器):单线程执行垃圾收集,收集时会暂停所有用户线程(STW,stop-the-world),优势是实现简单,内存占用小,适合单线程环境或客户端应用,这个收集器清理效率很高,但是在多核场景下无法有效利用cpu资源。

Parallel GC(并行收集器):多线程执行垃圾收集,仍会产生STW,但效率比Serial GC高。适合CPU核心数较多的场景,吞吐量优先。

CMS(并发标记清除收集器):号称停顿时间最短的收集器,以低延迟为目标,大部分工作与用户线程并发执行,减少STW时间,核心流程是:初始标记(STW)-> 并发标记 -> 重新标记(STW)-> 并发清除。它的优势在于STW时间短,适合响应时间敏感的应用。

G1(垃圾优先收集器):这个收集器是基于标记复制算法的,以一条线程去标记GCRoots可达的对象,此过程很快,需要停顿,然后再启动一个线程去做可达性分析,这个速度很慢,然后使用多条线程去回收废弃对象,也需要停顿。适用于大内存应用,对延迟和吞吐量都有要求的服务(如大型分布式系统)。

ZGC:jdk11引入的低延迟收集器,支持TB级别的大堆,STW时间极短,几乎不影响吞吐量,STW时间和堆大小无关,并支持并发压缩,无内存碎片,适合超大堆场景。适用于大型分布式系统,需要处理海量数据且堆延迟敏感的应用。

Shenandoah GC:jdk12引入,目标是低延迟,大堆支持,适用场景与ZGC类似。

如何判断当前 GC 策略是否合理?

1)full GC频率:生产环境应控制在1次/天,若频繁触发,说明内存配置或者对象生命周期有问题

2)GC停顿时间:YGC(年轻代GC):停顿时间应<100ms,频率可接受(如1次/分钟),full gc停顿时间应<1s ,否则会影响用户体验(如接口超时)

3)内存使用率:老年代内存使用率长期 > 80%,容易触发full gc,年轻代内存不足会导致YGC频繁

Full GC排查步骤

1)查看GC日志:分析full gc触发原因

2)分析内存泄漏:是否有大对象长期存活未被回收

3)检查jvm参数:老年代大小是否合理,元空间是否不足

4)优化对象生命周期:避免创建大量临时大对象,尽量复用对象,并及时释放

二、主流框架与中间件

1、Spring 是 Java 生态的基石,你能说说 Spring IoC 容器的初始化流程吗?Bean 的生命周期中,“初始化前”“初始化后” 有哪些扩展点?你在项目中用过哪些扩展点解决实际问题?

IOC容器的初始化流程:

主要分为bean加载和bean实例化两个阶段,核心步骤:

1)资源定位:通过ResourceLoader加载配置文件,将其转化为Resource对象

2)bean定义加载和解析:用beanDefinitionReader解析Resource中的bean标签或注解,将配置信息封装为BeanDefinition(包含类名,属性,依赖等)。

3)Bean定义注册:将BeanDefinition注册到BeanDefinitionRegistry中

4)Bean实例化:从BeanDefinitionRegistry中获取BeanDefinition,通过反射创建bean实例

5)bean初始化:依赖注入,通过AutowiredAnnotationBeanPostProcessor完成属性注入,并执行InitializingBean 接口的afterPropertiesSet() 或自定义 init-method

6)bean缓存:将初始化完成的bean放入单例池,后续直接从缓存获取。

bean生命周期的扩展点

1)BeanPostProcessor:bean实例化后,初始化前后调用,可用于aop代理或者字段加解密

2)InitializingBean:bean依赖注入完成后调用,可用于初始化资源,例如创建数据库连接池或者启动定时任务等

3)DisposableBean:容器关闭时调用,可用于释放资源,例如关闭连接池,停止线程池等

4)BeanFactoryPostProcessor:bean定义注册后,实例化前调用,可用于动态修改bean配置,如根据环境变量调整数据源URL

用 BeanPostProcessor 实现接口日志打印:

@Component
public class LogBeanPostProcessor implements BeanPostProcessor {// Bean 初始化前调用@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if (bean instanceof OrderService) {System.out.println("OrderService 实例化完成,准备初始化");}return bean;}// Bean 初始化后调用(若有 AOP 代理,此时 bean 已是代理对象)@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if (bean instanceof OrderService) {System.out.println("OrderService 初始化完成,可使用");}return bean;}
}

2、Spring 事务的传播机制和隔离级别分别有哪些?请举例说明 “事务传播机制 PROPAGATION_REQUIRES_NEW” 和 “PROPAGATION_NESTED” 的区别,以及实际项目中如何避免事务失效的问题?

传播机制:

REQUIRED(默认值):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务

SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行

MANDATORY:必须在一个已存在的事务中执行,如果当前没有事务,则抛出异常

REQUIRES_NEW:无论当前是否存在事务,都创建一个新事务,如果当前存在事务,则将当前事务挂起

NOT_SUPPORTED:以非事务的方式执行,如果当前存在事务,则将事务暂停

NEVER:以非事务方式执行;如果当前存在事务,则抛出异常

NESTED:如果当前存在事务,则在嵌套事务中执行,如果当前没有事务,则创建新事务

REQUIRES_NEW的特点是子事务和父事务完全独立,子事务回滚和提交不会影响父事务,例如订单创建作为父事务,调用日志记录作为子事务,即使日志记录失败回滚,订单创建仍可正常提交。

NESTED的特点是子事务依赖父事务,子事务回滚仅回滚自身,父事务回滚会连带子事务回滚,例如订单创建为父事务,包含库存扣减的子事务,库存扣减失败,订单创建可选择记录执行或者回滚,若订单创建回滚,库存扣减也会回滚。

隔离级别:

DEFAULT(默认值):默认值为READ_COMMITTED。

READ_UNCOMMITTED(读未提交):允许事务读取其他事务未提交的数据,可能出现脏读

READ_COMMITTED(读已提交):事务只能读取其他事务已经提交的数据,可以避免脏读,但是可能出现不可重复读

REPEATABLE_READ(可重复读):保证同一事务内多次读取同一数据的结果一致,可以避免脏读和不可重复读,但是会出现幻读

SERIALIZABLE(序列化读):最高隔离级别,强制事务串行执行,避免所有并发问题。

如何解决事务失效?

1)非public方法:@Transactional此注解仅对public方法生效,因为spring动态代理默认不拦截非public方法,解决办法就是将方法改为public,或者自定义AOP拦截非public方法

2)方法自调用:同一个类中,无事务方法调用有事务方法,因未经spring代理,事务不生效

示例:

@Service
public class OrderService {public void createOrder() {// 自调用,无事务doCreate(); }@Transactionalpublic void doCreate() { ... }
}

解决办法为通过AopContext.currentProxy()获取代理对象调用方法,或者将上述的doCreate方法拆分到另一服务类

3)异常被捕获:方法内捕获异常未抛出,spring无法感知异常,不会触发回滚。解决方法是捕获异常后手动抛出RunTimeException,或者通过TransactionStatus.setRollbackOnly()强制回滚

4)错误的异常类型:@Transactional 默认仅回滚RunTimeException和Error,不回滚checked异常(如IOException),解决办法是指定异常类型,例如:@Transactional(rollbackFor = Exception.class)

3、MyBatis 中,#{} 和 ${} 的区别是什么?为什么说 #{} 能防止 SQL 注入?MyBatis 的一级缓存和二级缓存分别是什么?在分布式项目中使用二级缓存需要注意什么问题?

#{}和${}的区别

1)#{}是参数占位符,${}时字符串替换

2)#{}是基于JDBCPreparedStatement的预编译SQL,${}是基于JDBCStatement,直接替换字符串

3)#{}无风险,参数会被视为“值”,自动加引号,${}有风险,参数会被视为sql片段,由sql注入的风险

4)#{}适用于传递参数,${}适用于传递sql片段

为什么#{}能够防止sql注入?

例如执行 select * from user where name = #{name}时,若参数name为“‘张三’ or ‘1’ = ‘1’ ”,mybatis会将其预编译为

select * from user where name = ?

执行时参数被当做字符串值传入,最终sql为

select * from user where name = '\'张三\' or \'1\'=\'1\''

不会被解析为sql逻辑,因此避免注入。

mybatis缓存机制

一级缓存:作用范围在用一个SqlSession内,执行相同的SQL,会从缓存中获取结果,避免重复查询数据库,当SqlSession关闭,或者执行insert、update,delete会清空一级缓存

二级缓存:作用范围是同一个SqlSessionFactory下的所有SqlSession,按照Mapper接口隔离,不同Mapper的缓存互不干扰;可通过全局配置 mybatis.configuration.cache-enabled=true(默认开启),或者在Mapper接口添加@CacheNamespace注解,使用二级缓存需要注意的是在分布式场景下,二级缓存的对象需要实现Serializable 序列化接口,因为缓存会将对象序列化到磁盘或内存,其次是一致性问题,多个服务节点的二级缓存独立,某个节点修改数据后,其他节点缓存未更新,导致数据不一致。所以分布式场景下不建议使用二级缓存,改用Redis分布式缓存,如果必须使用,需要通过mq发消息通知其他节点清空缓存

4、分布式系统中经常用到消息队列,你在项目中为什么选择某款消息队列?如何保证消息的 可靠性 和 不重复消费?如果消息队列出现消息堆积,你的处理方案是什么?

特性RabbitMQKafkaRocketMQPulsarActiveMQ
开发语言ErlangScala/JavaJavaJava/C++Java
核心定位企业级消息中间件(侧重灵活路由、可靠性)分布式流处理平台(侧重高吞吐、日志 / 大数据)分布式消息中间件(侧重金融级可靠性、事务)云原生流处理平台(融合队列 + 流处理)传统企业级消息中间件(功能全面但笨重)
可靠性高(支持持久化、镜像队列、DLQ)中高(分区副本机制,默认 3 副本)高(主从同步、事务消息、DLQ)高(分层存储、多副本、跨地域复制)高(支持多种持久化方案)
性能(吞吐量)中(万级 TPS)极高(十万级 TPS,支持批量读写)高(十万级 TPS)极高(与 Kafka 相当,支持分层存储优化)中(万级 TPS)
延迟低(毫秒级)中(毫秒级,批量场景下略高)低(毫秒级)低(毫秒级,流处理场景更优)中(毫秒级,复杂场景下延迟波动大)
扩展性中(集群扩展需手动配置,上限较低)高(横向扩展简单,支持上千节点集群)高(支持 Namesrv 水平扩展,集群能力强)极高(云原生设计,支持动态扩缩容)中(扩展复杂,不适合超大规模集群)
关键功能灵活路由(交换机模式)、延迟队列、镜像队列流处理(Kafka Streams)、日志聚合、分区副本事务消息、定时消息、消息回溯、批量消息队列 + 流处理融合、分层存储(冷热数据)、多租户支持多种协议(JMS、AMQP、MQTT 等)
运维成本中(Erlang 调试复杂,社区活跃)低(部署简单,生态工具丰富)中(需关注 JVM 调优,文档完善)中(云原生部署友好,学习曲线略陡)高(配置复杂,版本迭代慢)
生态兼容性好(支持多语言,适配 Spring、K8s)极好(大数据生态核心,适配 Flink/Spark)好(适配 Spring Cloud,金融场景工具全)好(云原生生态,适配 K8s、Flink)一般(传统生态,对新架构支持弱)
适用场景微服务通信、订单通知、延迟任务日志采集、用户行为分析、大数据流处理金融交易、分布式事务、高可靠业务云原生架构、混合队列 / 流处理场景、多租户传统企业内部系统、协议多样化场景
开源 / 商业开源(商业版为 RabbitMQ Cluster)开源(商业版为 Confluent Platform)开源(商业版为阿里云 ONS)开源(商业版为 StreamNative)开源(商业版为 ActiveMQ Artemis)

可靠性保证

从生产端,Broker端,消费者端分别分析:

生产端:开启消息确认,消息到达Broker后返回一条确认消息;失败重试,设置对应的重试次数,避免网络抖动导致的临时失败;本地消息表,核心业务用本地事务表+消息表双写,确保业务与消息发送原子性

Broker端:同步刷盘,消息写入后立即刷盘,避免Broker宕机导致内存中消息丢失;主从复制,开启Broker主从架构,主节点宕机后从节点接管,避免单点故障

消费者端:手动确认,关闭自动确认,确保消息消费完成后再确认,避免消费失败导致消息丢失

不重复消费保证

消息重复的原因可能有:生产者重试,Broker重试,消费者确认超时等,解决核心是“业务层面去重”

方案一:唯一消息ID+幂等表

生产者发送消息时,生成全局唯一ID放入消息头,消费者消费前,先查询数据库幂等表,如果已存在则跳过消费。如果不存在,消费后插入幂等表。

方案二:业务唯一键

利用业务自身的唯一键去重,例如订单ID,消费时先查询订单是否已存在,存在则不处理

消息堆积处理

消息堆积的核心原因可能是 消费速度 < 生产速度,解决思路分紧急处理和长期优化

紧急处理:扩容消费者,增加消费者实例数;或者创建临时消费队列,创建临时主题,将堆积消息分流到临时主题,用多个消费者组并行消费

长期优化:可简化消费流程,异步处理非核心步骤;或者调整Broker配置,增大Broker消息存储上限,避免因磁盘满导致消息丢弃;优化Broker刷盘策略。

5、分布式缓存Redis是提升系统性能的关键,你在项目中用 Redis 做过哪些场景?如何解决 Redis 的 “缓存穿透、缓存击穿、缓存雪崩” 问题?Redis 集群的架构原理是什么?

Redis核心应用场景

缓存:可以缓存热点数据,降低数据库压力,提升接口QPS

分布式锁:用SET key value NX EX 10命令实现分布式锁,解决并发抢单,库存超卖问题

计数器:用INCR命令实现点赞数,阅读量统计

限流器:用Redis+Lua脚本实现接口限流,防止恶意请求击垮服务

消息队列:用List结构的Lpush实现简单的消息队列

缓存的三大问题

缓存穿透:查询不存在的数据(如ID = -1),缓存和数据库都不命中,请求直达数据,解决方案是布隆过滤器或者空值缓存

缓存击穿:热点key过期瞬间,大量请求直达数据库,可使用互斥锁,查询数据库时枷锁,只让一个线程更新缓存,其他线程等待;热点key永不过期

缓存雪崩:大量key同时过期,或Redis集群宕机,请求全部到数据库,可使用过期时间加随机值,redis集群,或者服务降级等方案

Redis集群架构

主从架构:由1个主节点+N个从节点组成,主节点负责写操作,从节点负责读操作,从节点通过复制同步主节点数据,实现数据备份,缺点是主节点宕机后,需手动切换从节点为主节点,无法自动故障转移

哨兵架构:由主从架构+哨兵节点(通常3个)组成,可以监控主从节点状态,当主节点宕机时,自动选举从节点升级为主节点,并通知客户端新的主节点地址,缺点是无法解决数据分片问题,单主节点内存受限

Cluster集群架构:由多个主从节点组成,主节点之间通过Gossip协议通信,支持数据分片及故障转移,适用于海量数据,高并发读写的分布式场景

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

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

相关文章

Redis 主从复制、哨兵与 Cluster 集群部署

文章摘要 本文基于 VMware 虚拟机环境&#xff0c;详细讲解 Redis 高可用架构的核心组件与部署流程&#xff0c;涵盖三大核心模块&#xff1a;Redis 主从复制&#xff08;实现数据备份与读写分离&#xff09;、Redis 哨兵&#xff08;基于主从复制实现故障自动转移&#xff0c;…

ElementUI 中 validateField 对部分表单字段数组进行校验时多次回调问题

目录 方案一&#xff1a;循环调用 Promise.all 合并结果 方案二&#xff1a;直接传入数组字段 总结 在实际业务中&#xff0c;我们有时只需要对表单的部分字段进行校验。ElementUI 提供的 validateField 方法支持单个字段&#xff0c;也支持字段数组&#xff0c;但在使用时…

Visual Studio 2026 震撼发布!AI 智能编程时代正式来临

Visual Studio 2026 震撼发布&#xff01;AI 智能编程时代正式来临 Visual Studio 2026 Insider图标 开发者们的开发环境即将迎来前所未有的智能革命&#xff0c;微软用Visual Studio 2026 重新定义了编码体验。 2025年9月10日&#xff0c;微软正式推出了Visual Studio 2026 In…

Gamma AI:高效制作PPT的智能生成工具

你有没有过这种崩溃时刻&#xff1f;领导让你下午交一份产品介绍 PPT&#xff0c;你打开模板网站翻了半小时没找到合适的&#xff0c;好不容易选了个模板&#xff0c;又得手动调整文字间距、搭配图片&#xff0c;光是把数据做成图表就花了一小时&#xff0c;最后赶出来的 PPT 还…

Python副业新玩法:用Flask搭小程序后端,躺赚被动收入的秘密

凌晨1点&#xff0c;林浩合上电脑时&#xff0c;手机弹出一条微信消息——是上周帮一家社区水果店搭的小程序后端&#xff0c;商家发来了当月的服务费到账提醒。他靠在椅背上笑了&#xff1a;这是这个月第8笔“睡后收入”&#xff0c;加起来刚好覆盖了下个月的房贷。半年前&…

基于PyQt5和阿里云TTS的语音合成应用开发实战[附源码】

项目概述 本文将详细介绍一个基于PyQt5图形界面框架和阿里云TTS(Text-to-Speech)服务的语音合成桌面应用程序的开发过程。该应用提供了完整的文字转语音功能,包括多音色选择、参数调节、实时试听、语速调节和音频下载等特性。 技术栈 前端界面: PyQt5 语音合成: 阿里云TTS服…

基于esp32c3 rust embassy 的墨水屏程序

EPD Reader 基于ESP32-C3的电子墨水屏阅读器&#xff0c;支持ap 配网、sntp 时间同步、txt阅读、天气预报、显示节假日信息、农历显示、自动休眠、web配置等功能。这是在另一个项目 一个rust embassy esp32c3 的练习项目-CSDN博客的基础上修改的 。 界面比较粗糙&#xff0c;以…

Spring 单例测试及线程安全

创建一个账户类 package com.duanhw.demo22.account;import org.springframework.beans.factory.annotation.Value;//Service public class AccountService {Value("1000")private Integer balance;//存款public void deposit(Integer amount){int newbalance balanc…

【vue】组件宽度调整失效后,调整的方法

父容器布局限制 若组件放置在栅格布局&#xff08;如display: grid&#xff09;或弹性容器中&#xff0c;父元素的宽度限制可能导致子组件宽度失效。解决方案是为父容器设置明确的宽度&#xff0c;或通过百分比布局实现自适应16。例如&#xff1a; <div style"width:…

Java 在Word 文档中插入页眉页脚:一份实用的编程指南

在现代企业应用中&#xff0c;Java 开发者经常需要处理各种文档操作&#xff0c;其中对 Word 文档的自动化处理尤为常见。无论是生成报告、合同还是其他商业文档&#xff0c;页眉页脚作为文档结构的重要组成部分&#xff0c;承载着公司 Logo、页码、版权信息等关键内容。手动添…

深入解析Dart虚拟机运行原理

Dart虚拟机运行原理 一、Dart虚拟机 1.1 引言 Dart VM是一种虚拟机&#xff0c;为高级编程语言Dart提供执行环境&#xff0c;但这并意味着Dart在D虚拟机上执行时&#xff0c;总是采用解释执行或者JIT编译。 例如还可以使用Dart虚拟机的AOT管道将Dart代码编译为机器代码&#xf…

光谱相机在AI眼镜领域中的应用

一、核心应用场景‌健康监测系统‌‌实时生理指标分析‌&#xff1a;通过眼周皮肤光谱特征&#xff0c;监测血氧(SpO₂)和血红蛋白变化&#xff0c;精度可达2%‌血糖无创检测‌&#xff1a;近红外光谱(900-1700nm)分析泪液成分&#xff0c;临床测试相关系数R0.87‌疲劳度评估‌…

如何通过url打开本地文件文件夹

安装部署 https://github.com/jixn-hu/notion_link_opener 这是我自己开发的一个后端服务&#xff0c;要一直开着 部署好后 会打开一个前端页面填下好你文件或者文件夹 点击生成短链就可以直接打开本地的文件夹了

第一篇:如何在数组中操作数据【数据结构入门】

记录以下自己重温数据结构的笔记&#xff0c;附带自己实现的C代码&#xff0c; 其中部分Python代码是网上教程里的&#xff0c;顺手粘贴过来&#xff0c;做一对比/ &#xff08;Python确实简洁&#xff0c;但是C更好理解不是吗哈哈哈&#xff09;数组的定义 数组&#xff1a;线…

基于STM32的单片机开发复盘

硬件介绍 底盘&#xff1a;幻尔阿克曼底盘&#xff1b;2个直流霍尔电机、1个PWM舵机开发板&#xff1a;幻尔Ros Controller V1.2&#xff08;STM32F407VET6&#xff09;电源&#xff1a;因为是学习阶段&#xff0c;没有配电池&#xff0c;使用120W可调电源&#xff08;3V~12V&a…

面试常问:注册中心宕机,远程调用还能成功吗?

在微服务架构里&#xff0c;注册中心&#xff08;像 Nacos、Eureka、Consul 等&#xff09;是服务发现与治理的核心。可要是注册中心突然宕机&#xff0c;微服务间的远程调用还能顺利进行吗&#xff1f;这是面试时很常被问到的问题&#xff0c;下面我们就来深入剖析。一、远程调…

《用 Python 和 Matplotlib 绘制折线图:从入门到实战的可视化指南》

《用 Python 和 Matplotlib 绘制折线图:从入门到实战的可视化指南》 一、引言:数据可视化的力量,从一张折线图开始 在我多年的开发与教学经历中,最常被问到的问题之一是:“如何让数据更直观?”我的答案始终如一:用图说话。而在众多图表类型中,折线图以其简洁、清晰的…

Seate的XA模式和AT模式

目录 一、XA模式 【1】两阶段提交 【2】Seata的XA模型 【3】优缺点 【4】实现XA模式 二、AT模式 【1】Seata的AT模型 【2】AT与XA的区别 【3】脏写问题 【4】优缺点 【5】实现AT模式 一、XA模式 XA 规范 是 X/Open 组织定义的分布式事务处理&#xff08;DTP&#xf…

CTFHub SSRF通关笔记6:Gopher Redis原理详解与渗透实战

目录 一、SSRF Gopher Redis 1、功能简介 2、攻击原理 &#xff08;1&#xff09;SSR的作用 &#xff08;2&#xff09;Gopher 协议特性 &#xff08;3&#xff09;攻击 Redis 步骤 二、gopherus 1、功能简介 2、攻击Redis服务方法 三、Gopherus安装 1、源码下载 2…

数据结构之二叉树(2)

数据结构之二叉树&#xff08;2&#xff09;1.二叉树的存储结构2.实现顺序结构二叉树2.1何为堆2.2堆的性质2.3堆的定义2.3堆的初始化与销毁3.1向上调整算法3.2向下调整算法4.入堆5.出堆让花成花&#xff0c;让树成树上一次我们学习了树的分类&#xff0c;并初步了解了二叉树。今…