Servlet+tomcat

serverlet

定义:是一个接口,定义了java类被浏览器(tomcat识别)的规则
所以我们需要自定义一个类,实现severlet接口复写方法
通过配置类实现路径和servlet的对应关系
在这里插入图片描述

执行原理

在这里插入图片描述

  1. 当用户在浏览器输入路径,会解析请求的URL路径,获取访问的serverlet资源路径
  2. 查找web.xml文件,是否又对应的标签体内哦让那个
  3. 如果有,则在找到对应的的全类名
    4.tomcat会将字节码文件加载进内存,并创建器对象

生命周期

init方法:在Servelet被创建的时候执行,只会执行一次
serverce提供服务的方法,每次提供方法的时候就会执行
destory正常在服务器被关闭的时候会执行,只会执行一次

创建:默认情况下第一次被访问的时候被创建,或者通过配置文件修改为启动服务器的时候被创建-<load-on-startup> ,并且serverlet的类是单列的,是共享资源,所以不要定义成员变量

提供服务
销毁:在serverlet被销毁之前的时候执行,用来释放资源

SverlectConfig 获得serverlet的配置信息的
getServletConfig 获得serverlet的信息

可以使用 @WebServelet的注解配置去解读

ideal与tomcat的关系

会在日志中的server.xml里面修改对应的tomcat的文件
一个项目会存储在工作空间项目还有会存在tomcat的项目
tomcat真正的访问的是tomcat的项目这个项目对应的是工作空间的web目录下的所有还有一个class目录下里面存储的又工作空间编译生成的class类,并且在工作目录下中的WEB-INF下的资源无法部署在tomcat中

体系结构

静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源——可以直接返回给浏览器(有静态资源解析的引擎)
动态资源:所有用户访问后,得到的结果都是不一样的,称为动态资源——需要先转化成静态资源,然后返回给浏览器(响应)

URI:资源名称 共和国
URL:资源路径+资源名称 中华人民共和国

Request请求转发

服务器内部的资源跳转步骤
1.RequestDispatcher getRequestDispatcher(String path)这个方法用获得转发器对象
2. 使用RequstDispatcher对象进行转发:forward(ServletRequest request, ServletResponse response)

// 1. 获取转发器
RequestDispatcher requestDispatcher = request.getRequestDispatcher("转发的目标地址URI");
// 2. 使用转发器转发
requestDispatcher.forward(request, response);

特点:
浏览器地址栏路径不发生改变
只能访问当前服务器内部的URI,不能访问外部的资源
转发是一次请求,所以request对象和response对象都是同一个

共享数据

域对象:有作用范围的对象,在一定范围共享数据
默认域为一次请求
方法:
setAttribute(String name, Object value) 设置域数据在转发之前设置
getAttribute(String name) 获取域数据
removeAttribute(String name) 移除域数据
所以跨域问题,其实就是发送了两次请求,并且希望携带cookie,所以需要浏览器通过实现跨域问题,否则浏览器默认不允许跨域,防止CSRF攻击

tomcat

tomcat 自己的Main方法在startup文件夹之下boot_start

架构

在这里插入图片描述

TOMCAT不会直接调用servlet,而是调用servlet容器,让容器调用接口。容器先定位再判断是否存在servlet类,如果没有就加载一个然后调用服务再返回

设计是通过两个核心连接器(connector)和容器(cpmyaomer)来实现,连接器对外交流,容器对内部处理
在这里插入图片描述

连接器

架构:Coyote 作为独立的模块,只负责具体的协议和IO相关的操作
在这里插入图片描述

IO 模型
NIO:同步非阻塞IO,一个线程可以处理多个请求
NIO2:异步非阻塞IO,一个线程可以处理多个请求
APR:本地库,可以提高性能
一个容器可以对应多个连接器

在这里插入图片描述

可以通过调用适配器的方法将request转化为servletRequest的方法
EndPoint:是一个处理TCP请求的组件,是将具体的Socket接受和发送处理器
Processor:是对TCP/IP 传输过来的字节流进行解析即实现HTPP/AJP的解读成为一个Request对象

coyote:是连接器
Catalina:是容器的实现-实现具体的逻辑处理
在这里插入图片描述

Catalina

在这里插入图片描述

执行的原理是:
由Catalina开始解析配置文件,从而管理server,而server表示的是整个服务器。服务器下面有多个服务,每个服务可以连接多个连接器和一个容器

Container

存在四层结构是父子关系
Engine:引擎,管理多个虚拟主机/虚拟站点,一个容器内只能有一个引擎
Host:虚拟主机/站点——多个网站
Context:Context是特定Web应用的表示,就是一个项目
Wrapper:Wrapper是特定Servlet的表示,一个Wrapper代表一个Servlet,最底层的容器

tomcat启动流程

在这里插入图片描述

首先调用BootStrap的main()方法,对各个类进行初始化,初始化之后对各个类进行启动
父祖教调用自身并且启动子组件,最后启动PritocolHandler组件,进行监听和处理请求的

Lifecycle:是生命周期组件,可以监听组件的启动和关闭,并且可以调用组件的启动和关闭方法

请求处理流程

在这里插入图片描述

发送的请求首先经过连接器,连接器解析请求,然后交给引擎,引擎会解析本地的Host请求/DNS服务器去找到对应的IP地址,然后就是自己写的服务中的配置找到对应的映射即Context

EndPoint会启动Socket去接受到一个请求然后交给Processor去解析,然后交给CoyoteAdapter进行处理此时作为request请求,
他会先去Mapper去找到请求的路径映射映射,然后转化为Engina所需要的request请求,交给Host再到Context再到Wrapper
他就会构造一个过滤器链然后再执行各个过滤器最后执行servlet
在这里插入图片描述

pipeline:管道的作用就是传输valve——松耦合,责任链
根据请求方式决定执行哪个方法

Jasper

因为服务器最终响应到浏览器的最终只能是静态页面,所以不包含任何java相关的语法。
当浏览器发送的是一个jsp的请求的时候,服务器会先根据自己的JspServlet去寻找对应的index.jsp文件然后将他转化为java文件,在经过编译成为class的可执行文件,就会直接返回response给浏览器其中含有html的页面

运行时编译:即class文件一开始没有是变运行变编译的
在这里插入图片描述

预编译:一次性将所有的JSP页面编译完成,在启动tomcat的时候就编译完成

JSP编译原理
生成的java类之后会编译成为class文件里面就会包含的有html页面生成的函数

服务器的配置文件

server.xml文件(核心配置文件)——包含了容器的所有配置

<Listener /> 表示监听器  
<Service > 表示服务——创建Service实现  
<Executor /> 表示共享线程池,多个connector可以共享一个线程池,默认情况下各个使用的是自己线程池  
<Connector /> 表示连接器,可以通过配置Connector的配置去——里面有一个executor属性去指定共享线程池名称   
<Engine defaultHost="www.tomcat.com" name="Catalina"> 表示引擎,默认访问主机是localhost,name是引擎的名称  <Host appBase="webapps" name="www.tomcat.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
webapps 表示相对目录下的文件目录  
name 表示当前Host通用的网络名称,必须与DNS服务器上的注册信息一致。 
appBase 表示当前Host的根目录,默认是webapps    
unpackWARs="true" 表示是否解压当前下的WAR包,如果为true则将WAR包解压为文件夹,如果为false则不进行解压,但是仍然可以使用war包内的    
autoDeploy="true" 表示是否自动部署,如果为true则自动部署,如果为false则不自动部署  
修改name中的需要对应的dns或者本地host去替代  <Context docBase="webapps/ROOT" path="/" reloadable="true"/>
docBase 表示当前Context的根目录,默认是webapps/ROOT,就是表示访问的是哪一个文件夹  
path 表示当前Context的访问路径,默认是/,服务器的资源路径    
reloadable="true" 表示是否自动加载,如果为true则自动加载,如果为false则不自动加载  
</Host>    
</Engine> </Service>    

tomcat_users.xml文件——是对用户进行管理

web.xml文件

Web 应用配置

<context-param> 表示上下文参数,在这里设置的参数可以再servletContext中获取利用req.getServletContext().getAttribute("key")获取  
<param-name> 表示参数名称  </param-name>
<param-value> 表示参数值  </param-value>
</context-param>  

会话配置

浏览器和web服务器之间建立会话,会话是基于cookie的,cookie是基于session的

<session-config> 表示会话配置  
<session-timeout> 表示会话超时时间,单位为分钟,默认是30分钟  
</session-timeout>  
<cookie-config> 表示cookie配置  
<cookie-name> 表示cookie名称根据名称查sessionId  
<domain> 表示cookie的域名,默认是当前域名  
<http-only> 表示cookie是否只能通过http协议访问,默认是true,不能跨域  
<secure> 表示cookie是否只能通过https协议访问,默认是false     
<cookie-max-age> 表示cookie最大存活时间,单位为秒,默认是-1,表示浏览器关闭后cookie失效  
<tracking-mode> 表示cookie的跟踪模式,默认是COOKIE,表示cookie跟踪模式,可以设置为COOKIE或者URL    
</cookie-config>  
</session-config>  

可以通过application.getSession()获取session对象

servlet配置

主要包括servlet的配置和servlet-mapping的配置

<servlet> 
<servlet-name> 表示servlet名称  
<servlet-class> 表示servlet类  
<load-on-startup> 表示servlet的加载顺序,默认是0,表示在启动服务器的时候加载,如果为负数表示在服务器启动后加载,如果为正数表示在服务器启动前加载    
<enabled> 表示servlet是否启用,默认是true,表示启用,如果为false表示禁用    
</servlet>  
<servlet-mapping> 
<servlet-name> 表示servlet名称  
<url-pattern> 表示servlet的访问路径  
</servlet-mapping>  

监听器

<listener>

过滤器

拦截请求,用于认证、日志、加密、数据转化

<filter> 
<filter-name> 表示过滤器名称  
<filter-class> 表示过滤器类  
<async-supported> 表示过滤器是否支持异步,默认是false,表示不支持,如果为true表示支持    
</filter>  
<filter-mapping> 
<filter-name> 表示过滤器名称  
<url-pattern> 表示过滤器的访问路径  
</filter-mapping>  

欢迎页面和错误页面配置

<welcome-file-list> 
<welcome-file> 表示欢迎页面,默认的全局的欢迎页面    
</welcome-file>  
</welcome-file-list>//由于资源和网络占用会出现异常,不希望给用户查看    
<error-page> 
<error-code> 表示错误代码(404,500,403)  </error-code>
<location> 表示错误页面  </location>
</error-page>  

Tomcat管理配置

在tomcat-users.xml文件中配置用户名和密码

<role roleName="manager-gui"> 
<role roleName="admin-gui"> 
<user username="admin" password="admin" roles="manager-gui,admin-gui"/>

提供一个虚拟主机的管理页面

相对APP应用程序进行管理

<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user username="admin" password="admin" roles="manager-gui,manager-script,manager-jmx,manager-status"/>

JVM 的配置

JVM内存分配
在这里插入图片描述

集群

单个tomcat的承载能力是有限的,单排tomcat不能满足这需求,所以有一个nginx的负载均衡器,将请求分发到多个tomcat上,从而提高系统的吞吐量和可靠性。
负载均衡的测率:
轮询:将请求均匀的分配到多个tomcat上
加权轮询:根据tomcat的性能不同,分配不同的权重,性能好的分配的权重高,性能差的分配的权重低
ip_hash:根据ip地址分配,同一个ip地址的请求会分配到同一个tomcat上

集群的问题:
session共享问题
1.通过ip_hash方式,同一个请求访问的同一个ip所以session是共享的
2.session复制:将session复制到多个tomcat上,从而实现session共享,通过tomcat的广播机制——通过添加集群的配置。

在engine下添加集群的配置    
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">  <Manager className="org.apache.catalina.ha.session.DeltaManager"expireTime="10000"/>  
</Cluster>  

在web.xml中添加<distributable/>标签,表示当前的web应用是可分布的

3.单点登录——SSO
在这里插入图片描述

Tomcat的安全

配置安全
删除所有webapps下的项目
关闭删除用户所有权限
关闭/修改8005端口,修改关闭之类
设置错误页面
将密钥库文件复制到tomcat/conf目录下
修改server.xml文件

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"connectionTimeout="20000"scheme="https"secure="true"SSLEnabled="true"><SSLHostConfig certificateVerification="false"><Certificate certificateKeyFile="conf/localhost-rsa.jks"certificateFile="conf/localhost-rsa.jks"//密钥库文件certificateChainFile="conf/localhost-rsa.jks"//证书链文件type="RSA"  // 密钥库类型/></SSLHostConfig>
</Connector>

性能测试

yum install -y httpd-tools  
ab -v //查看版本  
上传war包  
并且移动到webapps下-里面剩余的其他文件全部删除  
ab -n 1000 -c 100 -p data.json http://192.168.1.100:8080/项目名/index.jsp    
-p表示post的是一个json格式文件  
-n表示总共请求次数  
-c表示并发数  

Jconslo可以查看远程的垃圾回收机制

连接器
maxConnections——当达到最大的连接数,服务器接受但不会处理更多的请求额外的请求会阻塞,知道连接数低于最大连接数
maxThreads——当达到最大的线程
acceptCount——最大的排队等待数量,就是maxConnections之后

WebSocket

是一个在浏览器和服务器之间建立一个不受限制的双向通信的协议
传统的的请求响应功能,可以使用轮询的方式,但是服务器的压力比较大。

websocket就不是Http这样请求响应的协议,而是一种全双通信,服务和客户端之间相互通信,基于http协议
在这里插入图片描述

相当于对http请求进行升级,相当于用ws作为开头地址

使用两种方式定义Endpoint:
第一种编程式子,继承javax.websocket.Endpoint类
第二种注解式子,使用@ServerEndpoint注解

@OnOpen-记录session,httpSession,在线会话,广播消息
@OnMessage-解析消息判定收件人,发送消息
@OnClose-销毁session,httpSession,在线会话,广播消息

相当于前端也有一个websocket的类然后也有特定的session只需要通过send指令就可以发送过去了
服务端始终只是使用一个类,通过使用session保存独有的websocket的所有信息,
httpSession表示在客户端与服务端传输的标记,onlineUser表示的就是用来确定此时请求的用户是谁

通过构造一个websocket的类,然后继承Endpoint类,然后重写方法

public class MyEndpointConfig extends ServerEndpointConfig.Configurator{@Overridepublic void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {HttpSession httpSession = (HttpSession)request.getHttpSession(); config.getUserProperties().put(HttpSession.class.getName(),httpSession);}
}@ServerEndpoint("/websocket",configuration=MyEndpointConfig.class)  //请求路径  
public class ChatSocket {private static Session session;  //用来表示记录websocket的session信息private static HttpSession httpSession;  //用来表示当前登录后的用户的httpSession  private static Map<HttpSession,Chatsocket> onlineUsers = new HashMap<>();  //用来表示记录的session@OnOpen  //表示打开会话的时候会触发的方法  //这里面的config就是用来获取HttpSession的,所以每次有人登录就会触发一次public void onOpen(Session session , EndpointConfig config){this.session = session;HttpSession httpSession = (HttpSession)config.getUserProperties().get(HttpSession.class.getName());this.httpSession = httpSession;if(httpSession.getAttribute("user") != null){onlineUsers.put(httpSession,this);}String name = getName(onlineUsers);// session.getBasicRemote().sendText(name);//表示发送单条数据给当前的会话  broadcast(name);//表示发送广播数据给所有的会话  }private String broadcast(String name){for(HttpSession httpSession : onlineUsers.keySet()){onlineUsers.get(httpSession).session.getBasicRemote().sendText(name);}}@OnMessage  //表示收到消息的时候会触发的方法  public void onMessage(String message,Session session){//1.获取客户端的消息并且解析  Map<String,String> messageMap = JSON.parseObject(message,Map.class);  String fromName = messageMap.get("fromName");String toName = messageMap.get("toName");String content = messageMap.get("content");if(toName != null && !toName.equals("")){return ;}String message = MessageUtil.getMessage(fromName,content);  singleMessage(message,fromName,toName);  
}private String singleMessage(String message,String fromName,String toName){  for(HttpSession httpSession : onlineUsers.keySet()){if(httpSession.getAttribute("user").equals(toName)){boolean flag = true;}}if(flag){for(HttpSession httpSession : onlineUsers.keySet()){if(httpSession.getAttribute("user").equals(toName)||httpSession.getAttribute("user").equals(fromName)){onlineUsers.get(httpSession).session.getBasicRemote().sendText(message);}}}}@OnClose  //表示关闭会话的时候会触发的方法  public void onClose(Session session,CloseReason closeReason){onlineUsers.remove(httpSession);}@OnError  //表示发生错误的时候会触发的方法  public void onError(Session session,Throwable throwable){throwable.printStackTrace();}}

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

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

相关文章

什么是 DDoS 攻击?高防 IP 如何有效防护?2025全面解析与方案推荐

一、DDoS 攻击&#xff1a;互联网时代的 “数字核武器” 1. DDoS 攻击的本质与原理 ** 分布式拒绝服务攻击&#xff08;DDoS&#xff09;** 通过操控海量僵尸设备&#xff0c;向目标服务器发送洪水般请求&#xff0c;耗尽带宽、连接或计算资源&#xff0c;导致合法用户无法访…

Circular Plot系列(一): 环形热图绘制

针对近期多个粉丝咨询环形图的绘制&#xff0c;我意识到&#xff0c;我们似乎没有真正介绍过circle图&#xff0c;但这一类图确是非常常用的图&#xff0c;所以这里详细学习一下circle的绘制&#xff0c;使用的是circlize包&#xff0c;功能很完善&#xff1a;安装包, #https:/…

【数据挖掘】时间序列预测-时间序列预测策略

时间序列预测策略 &#xff08;1&#xff09;单步预测与多步预测&#xff08;2&#xff09;直接多步预测&#xff08;3&#xff09;递归多步预测&#xff08;4&#xff09;直接递归的混合预测&#xff08;5&#xff09;多输入多输出预测 &#xff08;1&#xff09;单步预测与多…

【LLM】deepseek R1之GRPO训练笔记(持续更新)

note 相关框架对比&#xff1a; 需微调模型且资源有限 → Unsloth&#xff1b;本地隐私优先的小规模推理 → Ollama&#xff1b;复杂逻辑或多模态任务 → SGLang&#xff1b;高并发生产环境 → vLLM 微调SFT和GRPO是确实能学到新知识的四种格式&#xff08;messages、sharegpt…

【数据结构】--- 单链表的增删查改

前言&#xff1a; 经过了几个月的漫长岁月&#xff0c;回头时年迈的小编发现&#xff0c;数据结构的内容还没有写博客&#xff0c;于是小编赶紧停下手头的活动&#xff0c;补上博客以洗清身上的罪孽 目录 前言 概念&#xff1a; 单链表的结构 我们设定一个哨兵位头节点给链…

【JAVA】数据类型与变量:深入理解栈内存分配(4)

核心知识点详细解释 Java 的基本数据类型和引用数据类型 基本数据类型 Java 有 8 种基本数据类型&#xff0c;它们可以分为 4 类&#xff1a; 整数类型&#xff1a;byte&#xff08;1 字节&#xff09;、short&#xff08;2 字节&#xff09;、int&#xff08;4 字节&#…

ReentrantLock实现公平锁和非公平锁

在 Java 里&#xff0c;公平锁和非公平锁是多线程编程中用于同步的两种锁机制&#xff0c;它们的主要差异在于获取锁的顺序规则。下面是对二者的详细介绍&#xff1a; 公平锁 公平锁遵循 “先来先服务” 原则&#xff0c;也就是线程获取锁的顺序和请求锁的顺序一致。先请求锁…

一篇撸清 Http,SSE 与 WebSocket

HTTP,SSE 和WebSocket都是网络传输的协议,本篇快速介绍三者的概念和比较。 SSE(Server-Sent Events) 是什么? SSE(Server-Sent Events),服务器发送事件, 是一种基于 HTTP 的轻量级协议,允许服务器主动向客户端(如浏览器)推送实时数据。它设计用于单向通信(服务器到…

5个重要的财务指标讲解

1&#xff09;净资产收益率 2&#xff09;销售净利率 3&#xff09; 销售毛利率 4&#xff09;销售成本率 5&#xff09; 期间费用率 好的&#xff0c;我将通过一个假设的案例&#xff08;某公司2023年数据&#xff09;逐步解释这些财务指标&#xff0c;并用具体数字演示计算…

PISI:眼图1:眼图相关基本概念

0 英文缩写 TIE&#xff08;Time Interval Error&#xff09;时间间隔误差&#xff0c;UI&#xff08;Unit Interval&#xff09;单位间隔PDF&#xff08;Probability Density Function&#xff09;概率密度函数BER&#xff08;Bit Error Rate&#xff09;误码率TJ&#xff08…

前端八股 CSS 2 选择器

选择器功能&#xff1a;选中特定 DOM节点进行渲染 原始方法 getElementById() getElementByName() 现在方法选择器 分类&#xff1a; id选择器 类选择器 标签选择器 逻辑与选择器 其他类型选择器&#xff1a; 伪类选择器&#xff1a; :link&#xff1a;未被访问的链接…

算法竞赛进阶指南.闇の連鎖

目录 题目算法标签: 树上差分, L C A LCA LCA, 倍增思路代码 题目 352. 闇の連鎖 算法标签: 树上差分, L C A LCA LCA, 倍增 思路 对于一个无向图, 第一次切断树边, 第二次切非树边, 一共多少种方案使得图不连通, 点数和边数都很大, 时间复杂度不能是 O ( n 2 ) O(n ^ 2…

ActiveMQ 与其他 MQ 的对比分析:Kafka/RocketMQ 的选型参考(二)

ActiveMQ、Kafka 和 RocketMQ 详细对比 性能对比 在性能方面&#xff0c;Kafka 和 RocketMQ 通常在高吞吐量场景下表现出色&#xff0c;而 ActiveMQ 则相对较弱。根据相关测试数据表明&#xff0c;Kafka 在处理大规模日志数据时&#xff0c;单机吞吐量可以达到每秒数十万条甚…

Electron 从零开始:构建你的第一个桌面应用

&#x1f5a5;️ Electron 从零开始&#xff1a;构建你的第一个桌面应用 Electron 是一个可以使用 HTML、CSS 和 JavaScript 构建跨平台桌面应用的框架。它将 Chromium 和 Node.js 融合到一个环境中&#xff0c;使 Web 开发者也能轻松开发原生桌面应用。 &#x1f680; 什么是 …

相向双指针-16. 最接近的三数之和

16. 最接近的三数之和 题目描述思路讲解代码展示复杂度分析相关标签 题目描述 思路讲解 思路和 15. 三数之和 类似&#xff0c;排序后&#xff0c;枚举 nums[i] 作为第一个数&#xff0c;那么问题变成找到另外两个数&#xff0c;使得这三个数的和与 target 最接近&#xff0c;…

C 语 言 - - - 文 件 操 作

C 语 言 - - - 文 件 操 作 文 件文 件 名文 件 操 作fopenfclose 文 件 的 顺 序 读 写fputcfgetcfputsfgetsfprintffscanffwritefread 流文 件 的 随 机 读 写fseekftellrewind 总结 &#x1f4bb;作 者 简 介&#xff1a;曾 与 你 一 样 迷 茫&#xff0c;现 以 经 验 助 你…

Walrus 与 Pudgy Penguins 达成合作,为 Web3 头部 IP 引入去中心化存储

以将深受喜爱的数字藏品赋予生命而闻名的 IP 与品牌开发公司 Pudgy Penguins&#xff0c;现已集成 Walrus&#xff0c;用于存储和管理其日益增长的数字媒体资源库&#xff0c;包括在其产品和社区体验中使用的贴纸和 GIF。团队将率先通过 Tusky&#xff08;Walrus 的用户友好型文…

2019ICPC陕西省赛暨陕西邀请赛题解 BCDEF HIJKL

共111支队伍&#xff0c;获奖情况&#xff08;大概&#xff09; 铜牌66 —— 3 296 银牌33 —— 4 391 金牌 11 —— 6 808 题目难度&#xff08;过题&#xff09;L F E B C I J D K H Problem - L - Codeforces 思路&#xff1a;注意到答案是连乘&#xff0c;只要有0…

5块钱的无忧套餐卡可以变成流量卡吗

电信的 5 块钱无忧套餐卡理论上可以变成流量卡&#xff0c;但会受到一些条件限制&#xff0c;以下是具体介绍&#xff1a; 中国电信无忧卡简介 中国电信无忧卡是电信推出的低月租套餐&#xff0c;月租仅 5 元&#xff0c;包含 200M 国内流量、来电显示和 189 邮箱&#xff0c;全…

SpringBoot校园失物招领平台源码开发实现

概述 实用的​​SpringBoot校园失物招领平台​​完整项目源码&#xff0c;帮助开发者快速构建校园失物招领系统。该项目采用SpringBootVue前后端分离架构&#xff0c;包含完整的注册登录、信息发布、认领管理等模块&#xff0c;是学习企业级项目开发的优秀范例 主要内容 1. …