【SSM-SSM整合】将Spring、SpringMVC、Mybatis三者进行整合;本文阐述了几个核心原理知识点,附带对应的源码以及描述解析
SSM整合的基础jar包
需要创建的层级:
- controller层
- 该层下需要创建对应的控制器Servlet
- POJO文件夹
- 该层下需要创建与数据库对应的POJO类
- mapper层
- 该层下需要创建Mapper的接口实现
- service层
- 该层下需要创建业务层的接口及其接口实现
需要创建的配置文件:
ApplicationContext.xml(Spring核心配置文件)
-
组件扫描
<context:component-scan base-package="com.demonode"><!-- 排除controller层;因为controller层是由springMvc进行管理 --><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
-
配置数据源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm_integration"/><property name="user" value="root"/><property name="password" value="root"/> </bean>
-
配置mybatis
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 加载数据源--><property name="dataSource" ref="dataSource"></property><!-- 加载mybatis核心配置文件--><property name="configLocation" value="classpath:configuration.xml"></property> </bean> <!-- 扫描Mapper · 如果是注解,那么直接扫描接口的包 · 如果是xml配置文件,请扫描对应的包 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="configurer"><property name="basePackage" value="com.demonode.mapper"></property> </bean>
-
配置事务控制
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"><property name="dataSource" ref="dataSource"></property> </bean><!--配置事务增强方法 - *默认全部--> <tx:advice id="interceptor"><tx:attributes><tx:method name="*"/></tx:attributes> </tx:advice><aop:config><!--配置impl服务层下实现接口的所有方法都进行事务控制--><aop:advisor advice-ref="interceptor" pointcut="execution(* com.demonode.service.impl.*.*(..))"></aop:advisor> </aop:config>
Spring-mvc.xml(SpringMVC配置文件)
-
配置组件扫描
<!-- mvc只管理controller层就好 --> <context:component-scan base-package="com.demonode.controller"></context:component-scan>
-
配置MVC的注解驱动
<mvc:annotation-driven></mvc:annotation-driven>
-
配置内部视图解析器
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/page/"></property><property name="suffix" value=".jsp"></property> </bean>
-
开放内部资源
<mvc:default-servlet-handler></mvc:default-servlet-handler>
web.xml(WEB环境需要的配置文件)
-
配置Spring的核心配置文件
<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext.xml</param-value> </context-param>
-
配置监听器
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
-
配置Spring的核心控制器
<!-- 核心控制器Servlet --> <servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup> </servlet> <!-- servlet的映射地址 --> <servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern> </servlet-mapping>
-
配置过滤器
<!-- 过滤器配置 --> <filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param> </filter> <!-- 映射过滤器地址 --> <filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>
configuration.xml(Mybatis核心配置文件)
-
由于Mybatis的配置都交由Spring去管理了,所以该配置文件所能使用的功能挺少的。
-
配置变量
<typeAliases><typeAlias type="com.demonode.entityclass.Person" alias="person"></typeAlias> </typeAliases>
流程
流程图
- 其核心在于java的反射机制
- Spring核心:Java反射
- Mybatis:动态代理,而动态代理又是基于反射的。
- 所以,SSM框架核心原理在反射。
原理
Spring(对象工厂):
- 平时开发接触最多的估计就是这个IOC容器,它可以装载bean(也就是Java中的类,当然也包括service、dao里面的),有了这个机制,就不用在每次使用这个类的时候为它初始化,很少看到关键字new。
SpringMVC(视图控制器):
-
核心为一个DispatcherServlet,控制所有请求。
-
DispatcherServlet源码:
package servlet;import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties;import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import annotation.HController; import annotation.HRequestMapping;/*** 手写SpringMVC*/ public class MyDispatcherServlet extends HttpServlet {//加载属性文件private Properties properties = new Properties();//装载beannameprivate List<String> classNames = new ArrayList<String>();//ioc容器private Map<String, Object> ioc = new HashMap<String, Object>();//类似于以前自定义的cache缓存容器,这里也是起到一个容器的作用//用于加载各个mappingprivate Map<String, Method> handlerMapping = new HashMap<String, Method>();//容器加载所有的controllerprivate Map<String, Object> controllerMap = new HashMap<String, Object>();@Overridepublic void init(ServletConfig config) throws ServletException {// 1.加载配置文件doLoadConfig(config.getInitParameter("contextConfigLocation"));// 2.初始化所有相关联的类,扫描用户设定的包下面所有的类doScanner(properties.getProperty("scanPackage"));// 3.拿到扫描到的类,通过反射机制,实例化,并且放到ioc容器中beanName默认是首字母小写doInstance();// 4.初始化HandlerMapping(将url和method对应上)initHandlerMapping();}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {try {// 处理请求doDispatch(req, resp);} catch (Exception e) {resp.getWriter().write("500!! Server Exception");}}private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {if (handlerMapping.isEmpty()) {return;}String url = req.getRequestURI();String contextPath = req.getContextPath();url = url.replace(contextPath, "").replaceAll("/+", "/");if (!this.handlerMapping.containsKey(url)) {resp.getWriter().write("404 NOT FOUND!");return;}Method method = this.handlerMapping.get(url);// 获取方法的参数列表Class<?>[] parameterTypes = method.getParameterTypes();// 获取请求的参数Map<String, String[]> parameterMap = req.getParameterMap();// 保存参数值Object[] paramValues = new Object[parameterTypes.length];// 方法的参数列表for (int i = 0; i < parameterTypes.length; i++) {// 根据参数名称,做某些处理String requestParam = parameterTypes[i].getSimpleName();if (requestParam.equals("HttpServletRequest")) {// 参数类型已明确,这边强转类型paramValues[i] = req;continue;}if (requestParam.equals("HttpServletResponse")) {paramValues[i] = resp;continue;}if (requestParam.equals("String")) {for (Entry<String, String[]> param : parameterMap.entrySet()) {String value = Arrays.toString(param.getValue()).replaceAll("\\[|\\]", "").replaceAll(",\\s", ",");paramValues[i] = value;}}}// 利用反射机制来调用try {method.invoke(this.controllerMap.get(url), paramValues);// 第一个参数是method所对应的实例// 在ioc容器中} catch (Exception e) {e.printStackTrace();}}private void doLoadConfig(String location) {// 把web.xml中的contextConfigLocation对应value值的文件加载到流里面InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(location);try {// 用Properties文件加载文件里的内容properties.load(resourceAsStream);} catch (IOException e) {e.printStackTrace();} finally {// 关流if (null != resourceAsStream) {try {resourceAsStream.close();} catch (IOException e) {e.printStackTrace();}}}}private void doScanner(String packageName) {// 把所有的.替换成/URL url = this.getClass().getClassLoader().getResource("/" + packageName.replaceAll("\\.", "/"));File dir = new File(url.getFile());for (File file : dir.listFiles()) {if (file.isDirectory()) {// 递归读取包doScanner(packageName + "." + file.getName());} else {String className = packageName + "." + file.getName().replace(".class", "");classNames.add(className);}}}//利用java的反射机制private void doInstance() {if (classNames.isEmpty()) {return;}for (String className : classNames) {try {// 把类搞出来,反射来实例化Class<?> clazz = Class.forName(className);if (clazz.isAnnotationPresent(HController.class)) {ioc.put(toLowerFirstWord(clazz.getSimpleName()), clazz.newInstance());} else {continue;}} catch (Exception e) {e.printStackTrace();continue;}}}private void initHandlerMapping() {if (ioc.isEmpty()) {return;}try {for (Entry<String, Object> entry : ioc.entrySet()) {Class<? extends Object> clazz = entry.getValue().getClass();if (!clazz.isAnnotationPresent(HController.class)) {continue;}// 拼url时,是controller头的url拼上方法上的urlString baseUrl = "";if (clazz.isAnnotationPresent(HRequestMapping.class)) {HRequestMapping annotation = clazz.getAnnotation(HRequestMapping.class);baseUrl = annotation.value();}Method[] methods = clazz.getMethods();for (Method method : methods) {if (!method.isAnnotationPresent(HRequestMapping.class)) {continue;}HRequestMapping annotation = method.getAnnotation(HRequestMapping.class);String url = annotation.value();url = (baseUrl + "/" + url).replaceAll("/+", "/");handlerMapping.put(url, method);controllerMap.put(url, clazz.newInstance());System.out.println(url + "," + method);}}} catch (Exception e) {e.printStackTrace();}}/*** 把字符串的首字母小写* * @param name* @return*/private String toLowerFirstWord(String name) {char[] charArray = name.toCharArray();charArray[0] += 32;return String.valueOf(charArray);}}
-
从源码及可看出流程:
- 客户端发送请求到DispacherServlet(由web.xml拦截所有请求到改servlet);
- 由DispacherServlet(核心servlet)控制器查询HanderMapping,找到处理请求的Controller;(这里我用了一个map类似于缓存容器,装载所有的mapping即映射)
- Controller层调用业务逻辑处理后,返回ModelAndView,即下一层(往往是service、serviceimpl,mapper层)返回的的数据;
- DispacherServlet查询视图解析器,找到ModelAndView指定的视图;
- 视图负责将结果显示到客户端。
Mybatis(持久层框架)
-
mybatis是对jdbc的封装,它让数据库底层操作变的透明。
-
mybatis的操作都是围绕一个sqlSessionFactory实例展开的。
- mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。
- 在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再通过得到Mapper文件sqlSession.getMapper()
- 最后调用的是JDK的动态代理
protected T newInstance(MapperProxy<T> mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy) };
-
因此开发人员只需要创建Mapper接口,并使用Mapper接口即可。
-
Mybatis会对Mapper接口产生动态代理对象,这个动态代理对象实现了Mapper接口,拥有Mapper中定义的所有方法,并对这些方法进行了增强。增强的逻辑是获得sql语句和执行sql语句。
-
动态代理:
- 通过实现 InvocationHandler 接口创建自己的调用处理器;
- 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
- 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
- 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
框架核心原理
-
AOP 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足。
- 除了类(classes)以外,AOP提供了切面。切面对关注点进行模块化,例如横切多个类型和对象的事务管理。Spring的一个关键的组件就是AOP框架,可以自由选择是否使用AOP。提供声明式企业服务,特别是为了替代EJB声明式服务。
- 最重要的服务是声明性事务管理,这个服务建立在Spring的抽象事物管理之上。允许用户实现自定义切面,用AOP来完善OOP的使用可以把Spring AOP看作是对Spring的一种增强。AOP的实现乃至spring框架基本上核心代码都是基于Java语言的反射机制(所谓的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。)。
- AOP主要作用就是不通过修改源代码的方式、将非核心功能代码织入来实现对方法的增强。
- 那么Spring AOP的底层如何实现对方法的增强?实现的关键在于使用了代理模式。代理模式的作用就是为其它对象提供一种代理,以控制对这个对象的访问,用于解决在直接访问对象时带来的各种问题,比如要访问的对象在远程的机器上。
- 在面向对象系统中,由于其他某些原因(对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问)等
- 代理主要分为两种方式:静态代理和动态代理
-
IOC :IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
-
有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象。
-
所以相较于传统的java servlet需要自己request.getParamiter等需要一系列取值,转换中文,转换值类型的繁琐,
-
更重要的是使得程序的整个体系结构变得非常灵活。自定义一个IOC容器的思路:
- Map做一个容器,然后用解析xml文件的工具解析出需要扫描的包。利用Java反射机制拿到锁具有的方法,属性,注入到Map容器
-
-
DI 依赖注入,是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态地将某个依赖关系注入到组件之中。
- 依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。
- 通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
😍❤️SSM 专栏前篇
- 【SSM-Spring(一)】初上手Spring?别急!从最底部开始学习Spring吧!从Bean开始!本文介绍Spring程序的开发、Bean的声明周期与依赖注入概念
- 【SSM-Spring(二)】初上手Spring?别急!从最底部开始学习Spring吧!Spring连接数据库、注解开发、Junit测试
- 【SSM-SpringMVC(一)】Spring接入Web环境!本篇开始研究SpringMVC的使用!本文介绍了SpringMVC,以及SpringMVC的执行流程和常用注解解析
- 【SSM-SpringMVC(二)】Spring接入Web环境!本篇开始研究SpringMVC的使用!SpringMVC数据响应和获取请求数据
- 【SSM-Spring(三)】初上手Spring?别急!从最底部开始学习Spring吧!详细介绍SpringAOP切面编程操作和Spring编程式事务控制操作
- 【SSM-Mybatis(一)】java持久层框架-Mybatis!本文涵盖介绍Mybatis和基本使用,分析Mybatis核心配置文件
- 【SSM-Mybatis(二)】java持久层框架-Mybatis!本文重点对mybatis的映射文件进行了分析!涵盖if、foreach、choose、sql片段抽取、多表查询、注解开发等内容!
💕👉博客专栏
-
英语专栏-涵盖绝大多数的英语语法~~基于B站英语兔视频所作的学习笔记
-
Golang专栏-包含基础、Gin、Goam等知识
-
云原生专栏-包含k8s、docker等知识
-
从0开始学习云计算-华为HCIP证书
-
JUC专栏-带你快速领悟JUC的知识!
-
JVM专栏-深入Java虚拟机,理解JVM的原理
-
基于Java研究 数据结构与算法-包含贪心算法、加权图、最短路径算法等知识
-
Docker专栏-上手热门容器技术Docker
-
SpringBoot专栏-学习SpringBoot快速开发后端
-
项目管理工具的学习-设计技术:Maven、Git、Gradle等相关管理工具
-
JavaSE-全面了解Java基础
-
JS专栏-使用JS作的一部分实例~
-
使用CSS所作的一部分案例
相关文章:

【SSM-SSM整合】将Spring、SpringMVC、Mybatis三者进行整合;本文阐述了几个核心原理知识点,附带对应的源码以及描述解析
SSM整合的基础jar包 需要创建的层级: controller层 该层下需要创建对应的控制器Servlet POJO文件夹 该层下需要创建与数据库对应的POJO类 mapper层 该层下需要创建Mapper的接口实现 service层 该层下需要创建业务层的接口及其接口实现 需要创建的配置文件&#x…...
Go语言超时控制方案全解析:基于goroutine的优雅实现
一、引言 在构建高可靠的后端服务时,超时控制就像是守护系统稳定性的"安全阀",它确保当某些操作无法在预期时间内完成时,系统能够及时止损并释放资源。想象一下,如果没有超时控制,一个简单的数据库查询卡住…...
spark运行架构及核心组件介绍
目录 1. Spark 的运行架构1.1 Driver1.2 Executor1.3 Cluster Manager1.4 工作流程 2. Spark 的核心组件2.1 Spark Core2.2 Spark SQL2.3 Spark Streaming2.4 MLlib2.5 GraphX 3. Spark 架构图4. Spark 的优势4.1 高性能4.2 易用性4.3 扩展性4.4 容错性 5. 总结 1. Spark 的运行…...
idea中编写spark程序
### 在 IntelliJ IDEA 中配置和编写 Spark 程序 要在 IntelliJ IDEA 中高效地开发 Spark 程序,需要完成一系列必要的环境配置以及项目搭建工作。以下是详细的说明。 --- #### 1. 安装与配置 IntelliJ IDEA 为了确保 IDE 可以支持 Scala 开发,首先需要…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(21):复习
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(21):复习 1、前言(1)情况说明(2)工程师的信仰 2、知识点(1)じょうけん 条件形1、復習 (&#x…...

MYSQL数据库集群高可用和数据监控平台
项目环境 项目拓扑结构 软硬件环境清单 软硬件环境清单 软硬件环境清单 主机名IP硬件软件 master1 192.168.12.130 VIP:192.168.12.200 cpu:1颗2核 内 存:2GB HDD:20GB 网 络:NAT VmWare17 OpenEuler22.03 SP4 MySql8.0.3…...
Spark SQL 读取 CSV 文件,并将数据写入 MySQL 数据库
在 Spark 中,可以使用 Spark SQL 读取 CSV 文件,并将数据写入 MySQL 数据库。以下是一个完整的示例,展示如何实现这一过程。 环境准备 安装 MySQL:确保 MySQL 数据库已安装并运行。创建 MySQL 数据库和表:CREATE DAT…...
C++矩阵操作:正交矩阵(旋转矩阵)
文章目录 一、简介二、实现代码三、实现效果一、简介 我们知道判断一个矩阵的正交性可以看它是否符合以下条件: R T R = I R^TR=I R...
基于单片机的车灯智能控制系统设计与实现
标题:基于单片机的车灯智能控制系统设计与实现 内容:1.摘要 随着汽车行业的快速发展,车灯的智能化控制成为提升行车安全和驾驶体验的关键因素。本文旨在设计并实现一种基于单片机的车灯智能控制系统。采用单片机作为控制核心,结合光照传感器、雨滴传感器…...
机器学习第十一讲:标准化 → 把厘米和公斤单位统一成标准值
机器学习第十一讲:标准化 → 把厘米和公斤单位统一成标准值 资料取自《零基础学机器学习》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章:DeepSeek R1本地与线上满血版部署:超详细手把手指南 一、买菜…...

uni-app vue3版本打包h5后 页面跳转报错(uni[e] is not a function)
先看问题 解决方案 在HBuilderX项目中,若需在Web配置中显式关闭摇树优化(Tree Shaking),可以通过以下步骤实现:首先,在配置中打开摇树优化,然后再将其关闭。这样操作后,配置文件中会…...
大二java第一面小厂(挂)
第一场: mybatis怎么防止数据转义。 Hutool用的那些你常用的方法。 springboot的常用注解。 redis的多级缓存。 websocket怎么实现的多人协作编辑功能。 怎么实现的分库分表。 mysql里面的各种操作,比如说分表怎么分,分页查询怎么用。 mybat…...

【Redis】缓存穿透、缓存雪崩、缓存击穿
1.缓存穿透 是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,导致请求直接穿透缓存到达数据库,给数据库带来压力的情况。 常见的解决方案有两种: 缓存空对象:实现简单,维护方便&am…...
双目云台摄像机:双摄安防功能全方位
双目云台摄像机是一种具有革命性设计的云台摄像机设备,其核心在于其独特的双摄像头配置。以下是对这种先进安防设备的详细介绍: 一、核心原理 双目云台摄像机的核心原理在于利用两个摄像头从不同角度捕捉同一场景,通过先进的算法计算两个图…...

告别数据僵尸!Redis实现自动清理过期键值对
在这个数据爆炸的时代,内存就像珍贵的土地资源,而Redis则是这片土地上的智能管家。它不仅能高效存储数据,还能像秋叶定时凋零般,让键值对在指定时间自动消失。今天,就让我们揭开这项"数据保鲜"技术的奥秘。 …...

web第三次课后作业--基于JDBC对mysql数据库的增删查改操作
一、工程搭建步骤 1.新建java项目,添加jdbc依赖 2.写java程序 3.添加mysql数据源,连接本地数据库 4.运行程序二、运行结果 三、代码 代码解析 加载数据驱动 try {Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundExceptio…...
《P2345 [USACO04OPEN] MooFest G》
题目背景 P5094 [USACO04OPEN] MooFest G 加强版 题目描述 约翰的 n 头奶牛每年都会参加“哞哞大会”。 哞哞大会是奶牛界的盛事。集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等。 它们参加活动时会聚在一起,第 i 头…...
现代 Web 自动化测试框架对比:Playwright 与 Selenium 的深度剖析
现代 Web 自动化测试框架对比:Playwright 与 Selenium 的深度剖析 摘要:本文对 Playwright 与 Selenium 在开发适配性、使用难度、场景适用性及性能表现等方面进行了全面深入的对比分析。通过详细的技术实现细节阐述与实测数据支撑,为开发者…...
【网络协议】TCP、HTTP、MQTT 和 WebSocket 对比
从协议本质、工作原理、特点、应用场景等方面详细对比 TCP、HTTP、MQTT 和 WebSocket。 1. TCP(Transmission Control Protocol,传输控制协议) 本质 协议类型:传输层协议(OSI模型第4层)。核心功能&#x…...
Cython打包多层目录Python文件方法
为了使用Cython打包多层目录下的Python文件,并保持目录结构,请按照以下步骤操作: 步骤1:项目结构示例 假设项目结构如下: myproject/setup.pysrc/__init__.pymodule1.pysubdir/__init__.pymodule2.py步骤2ÿ…...

[数据结构]5. 栈-Stack
栈-Stack 1. 介绍2. 栈的实现2.1 基于链表的实现2.2 基于数组的实现 3. 栈操作CreateInitilizateDestoryPushPopTopEmptySize 1. 介绍 栈(stack) 是一种遵循先入后出逻辑的线性数据结构。顶部称为“栈顶”,底部称为“栈底”。把元素添加到栈…...
2020年下半年试题三:论云原生架构及其应用
论文库链接:系统架构设计师论文 论文题目 近年来,随着数字化转型不断深入,科技创新与业务发展不断融合,各行各业正在从大工业时代的固化范式进化成面向创新型组织与灵活型业务的崭新模式。在这一背景下,以容器盒微服务…...

基于Spring Boot + Vue的高校心理教育辅导系统
一、项目背景介绍 随着高校对学生心理健康教育的重视,传统的人工心理辅导与测评模式已经难以满足广大师生的个性化需求。为了提高心理服务的效率、便捷度和覆盖范围,本项目开发了一个高校心理教育辅导系统,集成心理评测、辅导预约、留言交流…...

JavaSwing之-JDialog
JavaSwing之-JDialog JDialog 是 Java Swing 中用于创建对话框窗口的容器类,继承自 Dialog 类(AWT),常用于显示临时信息、获取用户输入或执行模态操作。它是 javax.swing.JDialog 包中的类。 与 JFrame 不同的是,JDia…...

【学习路线】 游戏客户端开发入门到进阶
目录 游戏客户端开发入门到进阶:系统学习路线与推荐书单一、学习总原则:从底层出发,项目驱动,持续迭代二、推荐学习路线图(初学者→进阶)第一阶段:语言基础与编程思维第二阶段:游戏开…...

部署安装gitlab-ce-17.9.7-ce.0.el8.x86_64.rpm
目录 编辑 实验环境 所需软件 实验开始 安装部署gitlab171.配置清华源仓库(版本高的系统无需做)vim /etc/yum.repos.d/gitlab-ce.repo 2.提前下载包dnf localinstall gitlab-ce-17.9.7-ce.0.el8.x86_64.rpm --rocklinux 3.修改配…...

备战菊厂笔试2-BFS记忆化MLE?用Set去重-Set会TLE?用SortedSet剪枝
目录 200.岛屿数量 不用getnei,直接在dfs判断,去掉解包 如果害怕栈溢出那么可以用bfs 2617.网格图中最少访问的格子数 注意特判! MLE主要是因为vis占用的内存过大 用SortedSet有序剪枝 什么是SortedSet? 基本性质 导入 …...
主机A向主机B发送一个长度为L字节的文件,假设TCP的MSS为1460字节,则在TCP的序号不重复使用的前提下,L的最大值是多少?
📘题干回顾: 主机A向主机B发送一个长度为L字节的文件,假设TCP的MSS为1460字节,则在TCP的序号不重复使用的前提下,L的最大值是多少? 这个问题关键在于“TCP序号不重复使用”。 ✅ 正确答案是:D.…...

【RabbitMQ】发布确认机制的具体实现
文章目录 模式介绍建立连接单独确认代码实现逻辑运行结果 批量确认代码实现逻辑运行结果 异步确认实现逻辑介绍代码实现逻辑运行结果 三种策略对比以及完整代码 模式介绍 作为消息中间件,都会面临消息丢失的问题,消息丢失大概分为三种情况: …...

React状态管理-对state进行保留和重置
相同位置的相同组件会使得 state 被保留下来 当你勾选或清空复选框的时候,计数器 state 并没有被重置。不管 isFancy 是 true 还是 false,根组件 App 返回的 div 的第一个子组件都是 <Counter />: 你可能以为当你勾选复选框的时候 st…...