JavaWeb(后端实战)

news2026/3/19 6:05:39
登录功能需求在登录界面中输入用户的用户名以及密码点击 登录 按钮请求服务器服务端判断用户输入的用户名或者密码是否正确如果正确则返回成功结果前端跳转至系统首页面代码实现创建实体类 LoginInfo封装登录成功后返回给前端的数据//登录成功结果封装类 Data NoArgsConstructor AllArgsConstructor public class LoginInfo{ private Integer id;//员工ID private String username;//用户名 private String name;//姓名 private String token;//令牌 }LoginController:Slf4j RestController public class LoginController{ Autowired private EmpService empService; PostMapping(/login) public Result login(RequestBody Emp emp){ log.info(员工登录{},emp); LoginInfo loginInfo empService.login(emp); if(loginInfo!null){ return Result.success(loginInfo); } return Result.error(用户名或密码错误); } }EmpService:public interface EmpService{ /* ... */ //登录 LoginInfo login(Emp emp); }EmpServiceImpl://员工管理 Service public class EmpServiceImpl implements EmpService{ Autowired private EmpMapper empMapper; /* ... */ //登录 Override public LoginInfo login(Emp emp){ Emp empLogin empMapper.getUsernameAndPassword(emp); if(empLogin!null){ LoginInfo loginInfo new LoginInfo(empLogin.getId(),empLogin.getUsername(),empLogin.getName(),null); return loginInfo; } return null; } }EmpMapper:Mapper public interface EmpMapper{ //根据用户名和密码查询员工信息 Select(select * from emp where username #{username} and password #{password}) Emp getUsernameAndPassword(Emp emp); }测试前后端联调测试:存在问题当在浏览器新页面输入地址http://localhost:90 时未登录却仍然可以进入到后端管理系统页面此时就需要登录效验的实现解决该问题登录效验登录效验指的是在服务器端接收到浏览器发送过来的请求之后要对请求进行校验校验用户是否登录用户已经登录则直接执行对应的业务操作若用户没有登录就不允许执行相关的业务操作给前端响应一个错误的结果最终跳转到登录页面要求登录成功之后再来访问对应的数据HTTP 协议是无状态协议所谓无状态指的是每一次请求都是独立的下一次请求并不会携带上一次请求的数据而浏览器与服务器之间进行交互基于 HTTP 协议在通过浏览器来访问登陆这个接口实现了登陆的操作再执行其他业务操作时服务器并不知道该员工是否已登陆因为两次请求之间是独立的实现登录效验在员工登录成功后需要将用户登录成功的信息存起来记录用户已经登录成功的标记在浏览器发起请求时需要在服务端进行统一拦截拦截后进行登录校验涉及到 Web 开发中的两个技术会话技术用户登录成功之后在后续的每一次请求中都可以获取到该标记统一拦截技术过滤器 Filter、拦截器 Interceptor会话技术会话指的就是浏览器与服务器之间的一次连接在用户打开浏览器第一次访问服务器的时候这个会话就建立了直到有任何一方断开连接会话才结束了在一次会话当中可以包含多次请求和响应会话跟踪一种维护浏览器状态的方法服务器需要识别多次请求是否来自于同一浏览器以便在同一次会话的多次请求间共享数据使用会话跟踪技术就是要完成在同一个会话中多个请求之间进行共享数据会话跟踪方案Cookie(客户端会话跟踪技术)数据存储在客户端浏览器Session(服务端会话跟踪技术)数据存储在储在服务端令牌技术会话跟踪方案Cookie:Cookie 是基于 HTTP 协议的客户端会话跟踪技术客户端首次请求如登录后服务器通过响应头 Set-Cookie 携带用户数据如用户名、ID浏览器接收后会自动存储该 Cookie 到本地后续客户端每次请求时浏览器会通过请求头 Cook ie 自动将本地 Cookie 携带至服务器服务器通过判断请求中 Cookie 是否存在可识别客户端是否已登录实现同一会话中不同请求的数据共享优缺点优点HTTP 协议中支持的技术像 Set-Cookie 响应头的解析以及 Cookie 请求头数据的携带都是浏览器自动进行的无需手动操作缺点移动端 APP Android、IOS中无法使用 Cookie不安全用户可以自己禁用 CookieCookie 不能跨域跨域现在项目大部分都是前后端分离的前后端最终也会分开部署前端部署在服务器 192.168.150.200 上端口 80后端部署在 192.168.150.100 上端口 8080打开浏览器直接访问前端工程访问 urlhttp://192.168.150.200/login.html在该页面发起请求到服务端而服务端所在地址不再是 localhost而是服务器的 IP 地址 192.168.150.100假设访问接口地址为http://192.168.150.100:8080/login此时就存在跨域操作因为是在 http://192.168.150.200/login.html 这个页面上访问了http://192.168.150.100:8080/login 接口此时如果服务器设置了一个 Cookie这个 Cookie 是不能使用的因为 Cookie 无法跨域区分跨域的维度三个维度有任何一个维度不同就是跨域操作协议、IP / 协议、端口举例http://192.168.150.200/login.html ---------- https://192.168.150.200/login [协议不同跨域]http://192.168.150.200/login.html ---------- http://192.168.150.100/login [IP不同跨域]http://192.168.150.200/login.html ---------- http://192.168.150.200:8080/login [端口不同跨域]http://192.168.150.200/login.html ---------- http://192.168.150.200/login [不跨域]Sessioin:Session 是基于 Cookie 实现的服务器端会话跟踪技术客户端首次请求时服务器尝试获取 Session若不存在则自动创建每个 Session 对应唯一 IDSession ID服务器通过Set-Cookie 响应头将 Session ID 以名为JSESSIONID的 Cookie 形式响应给浏览器浏览器自动存储该 Cookie客户端后续请求时会自动携带JSESSIONIDCookie 到服务器服务器通过该 ID 从本地找到对应的 Session 对象从而实现同一会话中不同请求的数据共享优缺点优点Session 是存储在服务端的安全缺点服务器集群环境下无法直接使用 Session移动端 APPAndroid、IOS中无法使用 Cookie用户可以自己禁用 CookieCookie 不能跨域令牌技术令牌是用户身份标识的字符串是当前企业最常用的会话跟踪技术客户端发起登录请求登录成功后服务器生成令牌用户合法凭证并响应给前端前端接收令牌后可存储在 Cookie 或 localStorage 等空间后续请求中前端自动携带令牌到服务器服务器校验令牌有效性判断用户是否已登录如需共享数据可直接存储在令牌中优缺点:优点支持PC端、移动端解决集群环境下的认证问题减轻服务器的存储压力无需在服务器端存储缺点需要自己实现包括令牌的生成、令牌的传递、令牌的校验JWT 令牌最典型用于登录认证客户端登录成功后服务器生成 JWT 令牌并返回给前端前端存储 JWT后续每次请求均携带该令牌服务器统一拦截所有请求先判断是否携带令牌无令牌则拒绝访问有令牌则校验有效性有效则放行处理请求JWT 令牌基本概述JWT 全称 JSON Web Token 官网https://jwt.io/ 定义了一种简洁的、自包含的格式用于在通信双方以 JSON 数据格式安全的传输信息由于数字签名的存在这些信息是可靠的JWT 令牌由三个部分组成三个部分之间使用 . 来分割第一部分Header头 记录令牌类型、签名算法等例如{alg:HS256type:JWT}第二部分Payload有效载荷携带一些自定义信息、默认信息等例如{id:1userna me:Zhu}第三部分Signature签名防止 Token 被篡改、确保安全性将 header、payload并加入指定秘钥通过指定签名算法计算而来JWT 通过 Base64 编码将原始 JSON 数据转为字符串Base64 用 64 个可打印字符A-Z、a-z、0-9、、/表示二进制数据原始 JSON 字符串先被转换为二进制如 UTF-8 编码的字节流再按固定规则映射到这 64 个字符形成编码后的字符串若二进制数据长度不是 3 的倍数会用补位如长度为 4 时补 2 个Base64 是可逆的编码方式可通过解码还原原始 JSON仅用于将二进制数据转为字符串格式不具备加密安全性生成和效验使用 JWT 令牌需要先引入 JWT 的依赖!-- JWT依赖-- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency生成 JWT 令牌public class JwtTest{ //生成JWT令牌 - Jwts.builder() Test public void testGenJwt(){ MapString, Object claims new HashMap(); claims.put(id, 1); claims.put(username, Zhu); String jwt Jwts.builder().signWith(SignatureAlgorithm.HS256, Wmh1)//指定加密算法秘钥 .addClaims(claims) .setExpiration(new Date(System.currentTimeMillis() 12 * 3600 * 1000))//设置过期时间 .compact();//生成令牌 System.out.println(jwt); } }运行测试方法eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJaaHUiLCJleHAiOjE3NjE0NDQyMjl9.TkjYh_BJ7yq1YTSuhagYdDezgmHm4dCBpYmNvZO2k60输出的结果就是生成的 JWT 令牌通过英文的点分割对三个部分进行分割可以将生成的令牌复制到 JWT 的官网将生成的令牌放在 Encoded 位置此时就会自动的将令牌解析出解析 JWT//解析JWT令牌 - Jwts.parser() Test public void testParseJwt(){ Claims claims Jwts.parser().setSigningKey(Wmh1) .parseClaimsJws(eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJaaHUiLCJleHAiOjE3NjE0NDQyMjl9.TkjYh_BJ7yq1YTSuhagYdDezgmHm4dCBpYmNvZO2k60) .getBody(); System.out.println(claims); }运行测试方法{id1, usernameZhu, exp1761444229}注意篡改令牌中的任何一个字符在对令牌进行解析时都会报错JWT令牌过期后令牌就失效了解析的为非法令牌登录时生成创建 org.example.util 包创建 JwtUtils 类public class JwtUtils{ private static String signKey Wmh1;//秘钥 private static Long expire 43200000L; //生成JWT令牌 public static String generateJwt(MapString,Object claims){ String jwt Jwts.builder() .addClaims(claims) .signWith(SignatureAlgorithm.HS256, signKey) .setExpiration(new Date(System.currentTimeMillis() expire)) .compact(); return jwt; } //解析JWT令牌 public static Claims parseJWT(String jwt){ Claims claims Jwts.parser() .setSigningKey(signKey) .parseClaimsJws(jwt) .getBody(); return claims; } }EmpServiceImpl://员工管理 Service public class EmpServiceImpl implements EmpService{ Autowired private EmpMapper empMapper; /* ... */ //登录 Override public LoginInfo login(Emp emp){ Emp empLogin empMapper.getUsernameAndPassword(emp); if(empLogin ! null){ //生成JWT令牌 MapString,Object dataMap new HashMap(); dataMap.put(id, empLogin.getId()); dataMap.put(username, empLogin.getUsername()); String jwt JwtUtils.generateJwt(dataMap); LoginInfo loginInfo new LoginInfo(empLogin.getId(), empLogin.getUsername(), empLogin.getName(), jwt); return loginInfo; } return null; } }测试前后端联调测试JWT令牌已经响应给了前端此时就会将JWT令牌存储在浏览器本地后续的每一次请求都会将这个令牌携带到服务端而服务端需要统一拦截所有的请求从而判断是否携带的有合法的 JWT 令牌可以通过 Filter 过滤器Interceptorf 拦截器过滤器 Filter:Filter 表示过滤器是 JavaWeb 三大组件Servlet、Filter、Listener之一过滤器可以把对资源的请求拦截下来一般完成一些通用的操作比如登录校验、统一编码处理、敏感字符处理等使用过滤器之后要想访问服务器上的资源必须先经过滤器过滤器处理完毕之后才可以访问对应的资源快速入门定义过滤器创建 org.example.filter 包创建 DemoFilter 类实现 Filter 接口public class DemoFilter implements Filter{ //初始化方法, 服务器启动, 创建Filter实例时自动调用, 只调用一次 public void init(FilterConfig filterConfig) throws ServletException{ System.out.println(init ...); } //拦截到请求时,调用该方法,可以调用多次 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException{ System.out.println(拦截到了请求...); } //销毁方法, 服务器关闭时自动调用, 只调用一次 public void destroy(){ System.out.println(destroy ... ); } }配置过滤器在 Filter 类上添加注解WebFilter并指定属性urlPatterns通过这个属性指定过滤器要拦截哪些请求WebFilter(urlPatterns /*)//配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 ) public class DemoFilter implements Filter{ //初始化方法, 服务器启动, 创建Filter实例时自动调用, 只调用一次 public void init(FilterConfig filterConfig) throws ServletException{ System.out.println(init ...); } //拦截到请求时,调用该方法,可以调用多次 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException{ System.out.println(拦截到了请求...); } //销毁方法, 服务器关闭时自动调用, 只调用一次 public void destroy(){ System.out.println(destroy ... ); } }还需要在启动类上面加上注解ServletComponentScan通过这个注解来开启 SpringBoot 项目对于 Servlet 组件的支持ServletComponentScan//开启对Servlet组件的支持 SpringBootApplication public class TliasManagementApplication{ public static void main(String[] args){ SpringApplication.run(TliasManagementApplication.class, args); } }启动服务并打开浏览器可以看到控制台的输出注意在过滤器 Filter 中如果不执行放行操作将无法访问资源放行操作chain.doFilter(request, response);登录效验过滤器思路分析Filter 过滤器的流程步骤代码实现在 org.example.filter 包下创建 TokenFilter 类//令牌校验过滤器 Slf4j WebFilter(urlPatterns /*) public class TokenFilter implements Filter{ Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req;//转换为HTTP请求对象 HttpServletResponse response (HttpServletResponse) resp;//转换为HTTP响应对象 //获取请求url String url request.getRequestURL().toString(); //判断是否是登录请求 if(url.contains(login)){//登录请求 log.info(登录请求 , 放行); chain.doFilter(request, response);//放行 return; } //获取请求头中的令牌(token) String jwt request.getHeader(token); //判断令牌是否存在 if(!StringUtils.hasLength(jwt)){//jwt为空 log.info(获取到jwt令牌为空, 返回错误结果); response.setStatus(HttpStatus.SC_UNAUTHORIZED);//设置响应状态码为401 return; } //解析token try{ JwtUtils.parseJWT(jwt);//调用工具类解析令牌 }catch(Exception e){//解析失败 e.printStackTrace(); log.info(解析令牌失败, 返回错误结果); response.setStatus(HttpStatus.SC_UNAUTHORIZED);//设置响应状态码为401 return; } //放行 log.info(令牌合法, 放行); chain.doFilter(request , response);//允许请求继续访问目标接口 } }Filter 详解执行流程拦截路径拦截路径urlPatterns 值含义拦截具体路径/login只有访问 /login 路径时才会被拦截目录拦截/emps/*访问 /emps 下的所有资源都会被拦截拦截所有/*访问所有资源都会被拦截过滤器链过滤器链上过滤器的执行顺序注解配置的 Filter优先级是按照过滤器类名(字符串)的自然排序拦截器 Interceptor:拦截器是 Spring 框架中提供的用来动态拦截控制器方法的执行是一种动态拦截方法调用的机制类似于过滤器作用拦截请求在指定方法调用前后根据业务需要执行预先设定的代码快速入门自定义拦截器创建 org.example.interceptor 包创建 DemoInterceptor 类实现 HandlerInterceptor 接口并重写其所有方法//自定义拦截器 Component//标记为 Spring 组件,使其能被 Spring 容器扫描并管理 public class DemoInterceptor implements HandlerInterceptor{ //目标资源方法执行前执行 Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //handler: 被拦截的目标处理器(通常是 Controller 中的方法) System.out.println(preHandle .... ); return true;//true 表示放行 false 不放行 } //目标资源方法执行后执行 Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //modelAndView: 包含目标方法返回的模型数据(Model)和视图信息(View) System.out.println(postHandle ... ); } //视图渲染完毕后执行最后执行 Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //ex: 目标方法或视图渲染过程中抛出的异常(若有) System.out.println(afterCompletion .... ); } }注册配置拦截器创建 org.example.config 包创建 WebConfig 配置类实现 WebMvcConfigurer 接口并重写 addInterceprors 方法Configuration//标记该类为 Spring 的配置类 public class WebConfig implements WebMvcConfigurer{ //注入自定义的拦截器对象 Autowired private DemoInterceptor demoInterceptor; Override public void addInterceptors(InterceptorRegistry registry){//Spring MVC 提供的拦截器注册器 //注册自定义拦截器对象,并设置拦截器拦截的请求路径 registry.addInterceptor(demoInterceptor).addPathPatterns(/**);// /** 表示拦截所有请求 } }测试若将拦截器中返回值改为 false则没有响应数据说明被拦截了没有放行登录效验拦截器代码实现在 org.example.interceptor 包下创建 TokenInterceptor 类Slf4j Component public class TokenInterceptor implements HandlerInterceptor{ Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{ //获取请求url String url request.getRequestURL().toString(); //判断是否是登录请求 if(url.contains(login)){ //登录请求 log.info(登录请求, 放行); return true; } //获取请求头中的令牌(token) String jwt request.getHeader(token); //判断令牌是否存在 if(!StringUtils.hasLength(jwt)){ //jwt为空 log.info(获取到jwt令牌为空, 返回错误结果); response.setStatus(HttpStatus.SC_UNAUTHORIZED);//设置响应状态码为401 return false; } //解析token try { JwtUtils.parseJWT(jwt); } catch (Exception e) { e.printStackTrace(); log.info(解析令牌失败, 返回错误结果); response.setStatus(HttpStatus.SC_UNAUTHORIZED);//设置响应状态码为401 return false; } //放行 log.info(令牌合法, 放行); return true; } }配置拦截器Configuration//标记该类为 Spring 的配置类 public class WebConfig implements WebMvcConfigurer{ //注入自定义的拦截器对象 Autowired private TokenInterceptor tokenInterceptor; Override public void addInterceptors(InterceptorRegistry registry){//Spring MVC 提供的拦截器注册器 //注册自定义拦截器对象,并设置拦截器拦截的请求路径 registry.addInterceptor(tokenInterceptor).addPathPatterns(/**);// /** 表示拦截所有请求 } }Interceptor 详解拦截路径拦截路径的配置通过 addPathPatterns(要拦截路径) 方法可以指定要拦截哪些资源调用 excludePathPatterns (不拦截路径) 方法指定哪些资源不需要拦截Configuration public class WebConfig implements WebMvcConfigurer { //拦截器对象 Autowired private DemoInterceptor demoInterceptor; Override public void addInterceptors(InterceptorRegistry registry){ //注册自定义拦截器对象 registry.addInterceptor(demoInterceptor) .addPathPatterns(/**)//设置拦截器拦截的请求路径(/** 表示拦截所有请求) .excludePathPatterns(/login);//设置不拦截的请求路径 } }在拦截器中除了可以设置/**拦截所有资源外还有一些常见拦截路径设置:拦截路径含义举例/*一级路径能匹配 /depts/emps/login不能匹配 /depts/1/**任意级路径能匹配 /depts/depts/1/depts/1/2/depts/*/depts 下的一级路径能匹配 /depts/1不能匹配 /depts/1/2/depts/depts/**/depts 下的任意级路径能匹配 /depts/depts/1/depts/1/2不能匹配 /emps/1执行流程浏览器发起请求请求先被自定义过滤器拦截执行 放行前逻辑 后放行请求进入 Spring 环境放行后的请求首先到达 Spring Web 核心的DispatcherServlet (前端控制器)它是 Tomcat 能识别的 Servlet负责请求的分发拦截器预处理DispatcherServlet将请求转发给 Controller 前会触发自定义拦截器的preHandle()方法返回true放行请求继续流向 Controller 的接口方法返回false拦截请求终止不执行 Controller 方法执行 Controller 方法请求到达目标 Controller执行对应的接口业务逻辑拦截器后处理Controller 方法执行完成后依次触发拦截器的postHandle()(视图渲染前)和afterCompletion()视图渲染后方法返回与过滤器收尾拦截器后处理完成请求返回给DispatcherServlet再执行过滤器 放行后逻辑最终将响应数据返回给浏览器过滤器和拦截器的主要区别接口规范不同过滤器需要实现 Filter 接口而拦截器需要实现 HandlerInterceptor 接口拦截范围不同过滤器 Filter 会拦截所有的资源而 Interceptor 只会拦截 Spring 环境中的资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2425435.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…