Spring Boot 专家级面试题库

news2026/4/30 8:10:52
格式知识点原理 → 面试表达模板 → 追问应对一、自动配置原理高频必考Q1. Spring Boot 自动配置的原理是什么知识点讲解自动配置的核心链路分四步SpringBootApplication └── EnableAutoConfiguration └── AutoConfigurationImportSelector └── 读取 META-INF/spring/...AutoConfiguration.imports └── 每个自动配置类 Conditional 按条件装配 Bean关键机制ConditionalOnMissingBean保证用户自定义优先即用户自己定义了 Bean自动配置就不再创建实现开箱即用但可覆盖。Spring Boot 2.x vs 3.x 区别2.x配置类列表在META-INF/spring.factories3.x迁移到META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports性能更好启动更快面试表达模板SpringBootApplication包含EnableAutoConfiguration它通过AutoConfigurationImportSelector读取 classpath 下所有 jar 包的自动配置类列表然后用Conditional系列注解按条件筛选出实际需要创建的 Bean。核心设计是约定大于配置——只要引入了 Starter相关 Bean 就自动就绪但用户自定义的 Bean 始终优先ConditionalOnMissingBean。追问 1如何调试哪些自动配置类生效了# 启动时加参数打印自动配置报告java-jarapp.jar--debug# 或在 application.yml 中开启logging: level: org.springframework.boot.autoconfigure: DEBUG访问http://localhost:8080/actuator/conditions可以看到所有自动配置类的条件评估结果哪些匹配哪些不匹配及原因。Q2. 如何自定义一个 Starter知识点讲解Starter 依赖聚合模块starter-pom 自动配置模块autoconfigure分工明确my-log-spring-boot-starterstarter只有 pom.xml引入 autoconfigure my-log-spring-boot-autoconfigureautoconfigure包含配置逻辑 ├── MyLogProperties.java ← ConfigurationProperties 属性绑定 ├── MyLogService.java ← 核心功能 ├── MyLogAutoConfiguration.java ← AutoConfiguration 条件装配 └── META-INF/spring/...AutoConfiguration.imports ← 注册入口完整实现示例// 1. 属性类DataConfigurationProperties(prefixmy.log)publicclassMyLogProperties{privatebooleanenabledtrue;privateStringprefix[LOG];}// 2. 核心服务publicclassMyLogService{privatefinalMyLogPropertiesprops;publicMyLogService(MyLogPropertiesprops){this.propsprops;}publicvoidlog(Stringmsg){if(props.isEnabled())System.out.println(props.getPrefix() msg);}}// 3. 自动配置类AutoConfigurationConditionalOnClass(MyLogService.class)// classpath 有此类才生效EnableConfigurationProperties(MyLogProperties.class)publicclassMyLogAutoConfiguration{BeanConditionalOnMissingBean// 用户未自定义才创建publicMyLogServicemyLogService(MyLogPropertiesprops){returnnewMyLogService(props);}}面试表达模板Starter 分两个模块starter 只做依赖聚合autoconfigure 包含自动配置逻辑。核心是AutoConfigurationConditionalOnMissingBean前者让 Spring Boot 发现配置类后者保证用户自定义优先。META-INF 下的注册文件是 Spring SPI 机制的核心——启动时扫描所有 jar 包中的该文件汇总所有候选配置类。二、Bean 生命周期高频必考Q3. Bean 的生命周期有哪些阶段知识点讲解完整顺序14步 [实例化阶段] 1. 调用构造函数实例化 [属性注入阶段] 2. Autowired / Value 属性注入完成 [Aware 回调阶段] 3. BeanNameAware.setBeanName() 4. BeanFactoryAware.setBeanFactory() 5. ApplicationContextAware.setApplicationContext() [初始化阶段] 6. BeanPostProcessor.postProcessBeforeInitialization() 7. PostConstruct 方法 8. InitializingBean.afterPropertiesSet() 9. Bean(initMethod xxx) 10. BeanPostProcessor.postProcessAfterInitialization() ← AOP 代理在此创建 [使用阶段] 11. Bean 正常使用... [销毁阶段] 12. PreDestroy 方法 13. DisposableBean.destroy() 14. Bean(destroyMethod xxx)重要记忆点AOP 代理在第10步postProcessAfterInitialization创建所以在PostConstruct中拿到的this是原始对象不是代理PostConstruct推荐用于初始化依赖注入完成后执行PreDestroy推荐用于资源释放示例验证顺序ComponentSlf4jpublicclassLifecycleBeanimplementsBeanNameAware,InitializingBean,DisposableBean{AutowiredprivateSomeServicesomeService;// 步骤2属性注入OverridepublicvoidsetBeanName(Stringname){log.info(步骤3 BeanNameAware: {},name);}PostConstructpublicvoidpostConstruct(){log.info(步骤7 PostConstruct依赖已注入可安全使用 someService);// 常见用途初始化本地缓存、建立连接池、启动后台线程}OverridepublicvoidafterPropertiesSet(){log.info(步骤8 InitializingBean.afterPropertiesSet);}PreDestroypublicvoidpreDestroy(){log.info(步骤12 PreDestroy释放资源);// 常见用途关闭连接、清理临时文件、停止线程}Overridepublicvoiddestroy(){log.info(步骤13 DisposableBean.destroy);}}面试表达模板Bean 生命周期分四个阶段实例化→属性注入→初始化→销毁。开发中最常用的是PostConstruct初始化和PreDestroy销毁两者分别在属性注入完成后和容器关闭前调用。关键细节是 AOP 代理在postProcessAfterInitialization步骤创建这也是为什么同类内部方法调用绕过代理导致事务失效的根本原因。三、循环依赖高频必考Q4. Spring 如何解决循环依赖构造器注入为什么不能解决知识点讲解三级缓存的职责一级缓存 singletonObjects 存放完整 Bean实例化 属性注入 初始化全部完成 ↓ 业务代码获取 Bean 从这里取 二级缓存 earlySingletonObjects 存放早期引用已实例化属性注入未完成 ↓ 解决 AOP 场景确保循环引用中拿到的是代理对象而非原始对象 三级缓存 singletonFactories 存放 Bean 工厂ObjectFactory调用时生成早期引用 ↓ 打破循环的关键A 实例化后立即放入三级缓存解决过程A 依赖 BB 依赖 A1. 创建 A → 调用构造函数实例化 → 将 A 的 ObjectFactory 放入三级缓存 2. 注入 A 的属性需要 B→ 去创建 B 3. 创建 B → 实例化 B → 将 B 的 ObjectFactory 放入三级缓存 4. 注入 B 的属性需要 A→ 从三级缓存取出 A 的工厂 5. 调用工厂生成 A 的早期引用若 A 有 AOP此处生成代理→ 放入二级缓存 6. B 拿到 A 的引用完成属性注入 → B 初始化完成 → 放入一级缓存 7. A 拿到 B → 完成属性注入 → 初始化完成 → 放入一级缓存为什么构造器注入无法解决字段注入先实例化调构造函数再注入属性 → A 实例化完成后可以先放入三级缓存再去解决依赖 构造器注入实例化和注入同步进行参数必须在构造时传入 → A 构造时需要 BB 构造时需要 A永远无法开始实例化 → Spring 直接抛 BeanCurrentlyInCreationException面试表达模板Spring 通过三级缓存解决字段注入的循环依赖。核心思路是提前暴露Bean 实例化后立即将工厂函数放入三级缓存其他 Bean 需要它时可以提前拿到早期引用可能是 AOP 代理从而打破循环。构造器注入无法解决因为实例化和依赖注入同步进行无法提前暴露。Spring Boot 2.6 默认禁止循环依赖生产中遇到应优先重构代码解耦。四、事务高频必考Q5. Transactional 失效的场景有哪些知识点讲解事务基于 AOP 代理实现凡是绕过代理的场景都会导致失效。场景1同类内部方法调用最常见ServicepublicclassOrderService{// ❌ 调用 this.createLog()this 是原始对象不是代理publicvoidcreateOrder(){this.createLog();// 事务不生效}TransactionalpublicvoidcreateLog(){...}}// ✅ 正确方案注入自身代理ServicepublicclassOrderService{AutowiredprivateOrderServiceself;// Spring 注入的是代理对象publicvoidcreateOrder(){self.createLog();// 通过代理调用事务生效}TransactionalpublicvoidcreateLog(){...}}场景2非 public 方法// ❌ Spring AOP 只代理 public 方法TransactionalprotectedvoidinternalSave(){...}场景3异常被吃掉Transactionalpublicvoidsave(Useruser){try{userRepository.save(user);}catch(Exceptione){log.error(保存失败,e);// ❌ 异常被捕获Spring 认为正常不回滚}}// ✅ 正确捕获后重新抛出或手动标记回滚Transactionalpublicvoidsave(Useruser){try{userRepository.save(user);}catch(Exceptione){log.error(保存失败,e);TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();// 手动标记回滚}}场景4检查型异常默认不回滚// ❌ IOException 是检查型异常默认不回滚TransactionalpublicvoidreadAndSave()throwsIOException{thrownewIOException(IO 异常);// 不会回滚}// ✅ 显式指定回滚所有异常Transactional(rollbackForException.class)publicvoidreadAndSave()throwsIOException{...}面试表达模板Transactional失效主要有四类原因①同类内部调用绕过 AOP 代理最常见用自注入解决②方法非 publicAOP 限制③异常被捕获未重新抛出Spring 认为执行成功不回滚④检查型异常默认不回滚需指定rollbackFor Exception.class。排查时先确认代理是否生效再确认异常是否正常传播。五、AOP高频必考Q6. JDK 动态代理和 CGLIB 的区别Spring Boot 默认用哪个知识点讲解JDK 动态代理 原理通过反射生成实现了相同接口的代理类 限制目标类必须实现接口 性能调用时有反射开销 CGLIB 代理 原理继承目标类并重写所有非 final 方法 限制目标类/方法不能是 final 性能JDK 7 后与 JDK 代理性能接近 Spring Boot 2.x 起默认 CGLIB 原因无需实现接口更通用 配置EnableAspectJAutoProxy(proxyTargetClass true)默认已开启验证代理类型的示例SpringBootTestclassProxyTypeTest{AutowiredprivateUserServiceuserService;TestvoidcheckProxyType(){// Spring Boot 默认 CGLIB 代理System.out.println(userService.getClass().getName());// 输出类似com.example.UserServiceImpl$$SpringCGLIB$$0// 若是 JDK 代理com.sun.proxy.$Proxy28System.out.println(AopUtils.isCglibProxy(userService));// trueSystem.out.println(AopUtils.isJdkDynamicProxy(userService));// false}}面试表达模板JDK 动态代理要求目标类实现接口通过反射生成代理CGLIB 继承目标类重写方法不需要接口但 final 类/方法无法代理。Spring Boot 2.x 起默认 CGLIB所以没有接口的 Service 类也能被 AOP 代理。需要注意 final 方法如 Kotlin 默认 final无法被 CGLIB 代理会导致 AOP 失效。六、Redis 缓存高频必考Q7. 缓存穿透、击穿、雪崩的区别和解决方案知识点讲解三个问题的根本区别 缓存穿透查询的 key 在缓存和数据库都不存在 → 每次都打到 DB可被攻击者利用大量不存在的 key 缓存击穿热点 key 在某一时刻过期 → 瞬间大量并发同时打到 DB仅一个 key 的问题 缓存雪崩大量 key 同时过期或 Redis 宕机 → 大量请求同时打到 DB大规模问题解决方案对比问题方案代码要点穿透缓存空值set key EX 60穿透布隆过滤器启动时加载全量 ID 到 Bloom Filter击穿互斥锁SETNX lock 1 EX 10只有一个线程查 DB击穿逻辑过期不设 TTL由后台线程异步刷新雪崩TTL 随机偏移TTL 基础值 random(0, 300)雪崩Redis 高可用主从哨兵 / Cluster雪崩本地缓存兜底Caffeine 作为二级缓存击穿解决方案示例互斥锁publicUsergetUser(Longid){StringcacheKeyuser:id;// 1. 查缓存Useruser(User)redisTemplate.opsForValue().get(cacheKey);if(user!null)returnuser;// 2. 缓存未命中抢互斥锁只有一个线程能查 DBStringlockKeylock:user:id;BooleanlockedredisTemplate.opsForValue().setIfAbsent(lockKey,1,10,TimeUnit.SECONDS);if(Boolean.TRUE.equals(locked)){try{// 3. 双重检查防止锁等待期间另一线程已刷新缓存user(User)redisTemplate.opsForValue().get(cacheKey);if(user!null)returnuser;// 4. 查 DB 并写缓存useruserRepository.findById(id).orElse(null);if(user!null){redisTemplate.opsForValue().set(cacheKey,user,30,TimeUnit.MINUTES);}else{// 防穿透空值也缓存短 TTLredisTemplate.opsForValue().set(cacheKey,NULL,5,TimeUnit.MINUTES);}returnuser;}finally{redisTemplate.delete(lockKey);// 必须释放锁}}else{// 未抢到锁短暂等待后重试Thread.sleep(50);returngetUser(id);}}面试表达模板三个问题要分清楚穿透是 key 根本不存在用布隆过滤器或缓存空值击穿是热点 key 某一刻过期用互斥锁或逻辑过期雪崩是大量 key 同时失效TTL 加随机值散开配合 Redis 高可用和本地缓存兜底。生产中三种情况往往叠加出现需要综合防御。七、JVM 调优专家题Q8. 线上 CPU 飙高如何排查知识点讲解CPU 飙高的常见原因死循环、大量 GCFull GC频繁、大量线程上下文切换。标准排查步骤# 步骤1找到 CPU 最高的进程top-c# 记录 Java 进程的 PID假设是 12345# 步骤2找到进程内 CPU 最高的线程-H 显示线程top-H-p12345# 找到 CPU 最高的线程 TID假设是 12360# 步骤3将 TID 转为十六进制jstack 输出用十六进制printf%x\n12360# 输出3048# 步骤4查看线程堆栈jstack12345|grep-A30nid0x3048# 找到对应线程的调用栈定位到具体代码行步骤5常见问题识别看到 GC 相关线程GC task thread飙高 → Full GC 频繁 → 查看 jstat -gcutil 12345 1000 → 若老年代O列接近100%说明内存泄漏 → 用 jmap -dump:formatb,fileheap.hprof 12345 导出堆用 MAT 分析 看到业务线程在 RUNNABLE 状态栈顶是业务代码 → 代码死循环正则表达式回溯、while 无出口等 → 根据栈信息定位具体代码 看到大量线程在 BLOCKED 状态 → 锁竞争激烈synchronized 或 DB 连接池耗尽 → 考虑锁优化或增加连接池大小面试表达模板排查 CPU 飙高分三步①top -H -p PID找到 CPU 高的线程 TID②将 TID 转十六进制用jstack找到线程堆栈③根据线程状态判断原因RUNNABLE 且栈顶是业务代码 → 死循环GC 线程飙高 → 频繁 Full GC用jstat -gcutil确认再用堆 dump 分析内存泄漏大量 BLOCKED → 锁竞争或资源耗尽。八、面试自测表题目能否讲清原理能否写出代码能否应对追问自动配置链路Bean 生命周期14步三级缓存解决循环依赖Transactional 失效4种场景JDK代理 vs CGLIB缓存穿透/击穿/雪崩区别CPU飙高排查步骤自定义Starter步骤九、Spring MVC 请求链路高频Q9. 一个 HTTP 请求在 Spring MVC 内部的完整流程知识点讲解理解此流程是排查 404/415/400 的核心也是面试必问题。HTTP Request ↓ DispatcherServlet.doDispatch() ↓ ① HandlerMapping找处理器 RequestMappingHandlerMapping → 返回 HandlerExecutionChain Handler 匹配的 HandlerInterceptor 列表 ↓ ② HandlerAdapter执行处理器 RequestMappingHandlerAdapter ↓ HandlerMethodArgumentResolver解析参数 RequestParam → RequestParamMethodArgumentResolver RequestBody → RequestResponseBodyMethodProcessor └── HttpMessageConverterJSON→Java对象 PathVariable → PathVariableMethodArgumentResolver Valid → 触发 JSR-303 参数校验 ↓ 执行 Controller 方法 ↓ HandlerMethodReturnValueHandler处理返回值 ResponseBody → RequestResponseBodyMethodProcessor └── HttpMessageConverterJava对象→JSON ↓ ③ HandlerInterceptor 链 preHandle() ← Controller 执行前返回 false 则中断 postHandle() ← Controller 执行后视图渲染前 afterCompletion ← 请求完成即使有异常也会执行 ↓ ④ ExceptionHandlerExceptionResolver ExceptionHandler / RestControllerAdvice 处理异常根据状态码快速定位问题404 → HandlerMapping 找不到匹配的处理器 检查路径是否正确、RequestMapping 是否在 RestController 类上 405 → 路径匹配但 HTTP 方法不匹配 检查GetMapping vs PostMapping 是否对应 415 → Content-Type 不被支持没有合适的 MessageConverter 检查是否引入了 jackson-databindRequestBody 方法请求头是否有 Content-Type:application/json 400 → 参数绑定失败Valid 校验失败 → MethodArgumentNotValidException 全局异常处理中捕获并返回友好错误信息面试表达模板Spring MVC 的核心是DispatcherServlet一次请求依次经过①HandlerMapping找到 Controller 方法②HandlerAdapter解析参数MessageConverter 反序列化 JSON、执行方法、序列化返回值③HandlerInterceptor链前置/后置拦截④ExceptionHandlerExceptionResolver统一处理异常。掌握这条链路任何 HTTP 错误码都能快速定位根因。十、Spring Security安全Q10. JWT 认证的完整流程知识点讲解JWT 认证流程无状态不需要服务端存储 Session 登录阶段 客户端 POST /auth/login (username, password) ↓ UsernamePasswordAuthenticationFilter 拦截 ↓ AuthenticationManager → UserDetailsService 加载用户 ↓ PasswordEncoder 校验密码 ↓ 认证成功 → 生成 JWT含 userId、roles、过期时间 ↓ 返回 JWT 给客户端客户端存 localStorage / Cookie 后续请求阶段 客户端每次请求携带 Header: Authorization: Bearer JWT ↓ 自定义 JwtAuthenticationFilterOncePerRequestFilter ↓ 解析 JWT → 校验签名、检查过期时间 ↓ 从 JWT 中提取 userId、roles ↓ 将认证信息设置到 SecurityContextHolder ↓ FilterChain 继续执行后续过滤器和 Controller 可获取当前用户JWT 工具类ComponentpublicclassJwtUtil{// 建议从配置文件读取生产不要硬编码Value(${jwt.secret})privateStringsecret;Value(${jwt.expiration:86400})// 默认24小时privatelongexpirationSeconds;// 生成 JWTpublicStringgenerateToken(LonguserId,ListStringroles){returnJwts.builder().subject(userId.toString()).claim(roles,roles).issuedAt(newDate()).expiration(newDate(System.currentTimeMillis()expirationSeconds*1000)).signWith(getKey()).compact();}// 解析 JWT失败会抛 JwtExceptionpublicClaimsparseToken(Stringtoken){returnJwts.parser().verifyWith(getKey()).build().parseSignedClaims(token).getPayload();}privateSecretKeygetKey(){returnKeys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));}}// JWT 过滤器集成到 Spring Security 过滤器链ComponentRequiredArgsConstructorpublicclassJwtAuthFilterextendsOncePerRequestFilter{privatefinalJwtUtiljwtUtil;OverrideprotectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainchain)throwsIOException,ServletException{StringauthHeaderrequest.getHeader(Authorization);if(authHeader!nullauthHeader.startsWith(Bearer )){StringtokenauthHeader.substring(7);try{ClaimsclaimsjwtUtil.parseToken(token);LonguserIdLong.parseLong(claims.getSubject());// 将用户信息放入 SecurityContext后续可用 AuthenticationPrincipal 获取UsernamePasswordAuthenticationTokenauthnewUsernamePasswordAuthenticationToken(userId,null,((ListString)claims.get(roles)).stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));SecurityContextHolder.getContext().setAuthentication(auth);}catch(JwtExceptione){response.sendError(HttpServletResponse.SC_UNAUTHORIZED,Token 无效);return;}}chain.doFilter(request,response);}}面试表达模板JWT 认证是无状态的服务端不存 Session用私钥签发 Token校验时用公钥或相同密钥验证签名。流程是登录成功 → 生成 JWT → 客户端每次请求携带 → 自定义过滤器解析 JWT → 写入 SecurityContext → Controller 通过AuthenticationPrincipal获取当前用户。优点是水平扩展方便无需共享 Session缺点是 Token 签发后无法主动失效需要维护黑名单 Redis。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…