Spring Boot中如何编写优雅的单元测试
单元测试是指对软件中的最小可测试单元进行检查和验证。在Java中,单元测试的最小单元是类。通过编写针对类或方法的小段代码,来检验被测代码是否符合预期结果或行为。执行单元测试可以帮助开发者验证代码是否正确实现了功能需求,以及是否能够适应应用环境或需求变化。
本文将介绍如何在Spring Boot中编写优雅的单元测试,包括如何添加单元测试依赖,如何对不同层次的组件进行单元测试,以及如何使用Mock对象来模拟真实对象行为。本文假设读者已经对Spring Boot和单元测试有一定的了解和基础。
目录
一、Spring Boot中的单元测试依赖
二、Spring Boot中不同层次的单元测试
service层
Controller层
Repository层
三、Spring Boot中Mock对象的使用
总结
一、Spring Boot中的单元测试依赖
在Spring Boot项目中,要进行单元测试,首先需要添加相应的依赖。如果使用Maven作为构建工具,可以在pom.xml文件中添加以下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
这个依赖包含了多个库和功能,主要有以下几个:
- JUnit:JUnit是Java中最流行和最常用的单元测试框架,它提供了一套注解和断言来编写和运行单元测试。例如@Test注解表示一个测试方法,assertEquals断言表示两个值是否相等。
- Spring Test:Spring Test是一个基于Spring的测试框架,它提供了一套注解和工具来配置和管理Spring上下文和Bean。例如@SpringBootTest注解表示一个集成测试类,@Autowired注解表示自动注入一个Bean。
- Mockito:Mockito是一个Java中最流行和最强大的Mock对象库,它可以模拟复杂的真实对象行为,从而简化测试过程。例如@MockBean注解表示创建一个Mock对象,when方法表示定义Mock对象的行为。
- Hamcrest:Hamcrest是一个Java中的匹配器库,它提供了一套语义丰富而易读的匹配器来进行结果验证。例如assertThat断言表示验证一个值是否满足一个匹配器,is匹配器表示两个值是否相等。
- AssertJ:AssertJ是一个Java中的断言库,它提供了一套流畅而直观的断言语法来进行结果验证。例如assertThat断言表示验证一个值是否满足一个条件,isEqualTo断言表示两个值是否相等。
除了以上这些库外,spring-boot-starter-test还包含了其他一些库和功能,如JsonPath、JsonAssert、XmlUnit等。这些库和功能可以根据不同的测试场景进行选择和使用。
二、Spring Boot中不同层次的单元测试
service层
Service层是指封装业务逻辑和处理数据的层,它通常使用@Service或@Component注解来标识。在Spring Boot中,对Service层进行单元测试,可以使用@SpringBootTest注解来加载完整的Spring上下文,从而可以自动注入Service层的Bean。同时,可以使用@MockBean注解来创建和注入其他层次的Mock对象,从而避免真实地调用其他层次的方法,而是模拟其行为。
例如,假设有一个UserService类,它提供了一个根据用户ID查询用户信息的方法:
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}
}
要对这个类进行单元测试,可以编写以下测试类:
@SpringBootTest
public class UserServiceTest {@Autowiredprivate UserService userService;@MockBeanprivate UserRepository userRepository;@Testpublic void testGetUserById() {// 创建一个User对象User user = new User();user.setId(1L);user.setName("Alice");user.setEmail("alice@example.com");// 当调用userRepository.findById(1L)时,返回一个包含user对象的Optional对象when(userRepository.findById(1L)).thenReturn(Optional.of(user));// 调用userService.getUserById方法,传入1L作为参数,得到一个User对象User result = userService.getUserById(1L);// 验证结果对象与user对象相等assertThat(result).isEqualTo(user);// 验证userRepository.findById(1L)方法被调用了一次verify(userRepository, times(1)).findById(1L);}
}
在这个测试类中,使用了以下几个关键点和技巧:
- 使用@SpringBootTest注解表示加载完整的Spring上下文,并使用@Autowired注解将UserService对象注入到测试类中。
- 使用@MockBean注解表示创建一个UserRepository的Mock对象,并使用@Autowired注解将其注入到测试类中。这样可以避免真实地调用UserRepository的方法,而是模拟其行为。
- 使用when方法来定义Mock对象的行为,例如当调用userRepository.findById(1L)时,返回一个包含user对象的Optional对象。
- 使用userService.getUserById方法调用被测方法,得到一个User对象。
- 使用AssertJ的断言语法来验证结果对象与user对象是否相等。可以使用多种条件和匹配器来验证结果。
- 使用verify方法来验证Mock对象的方法是否被调用了指定次数。
Controller层
Controller层是指处理用户请求和响应的层,它通常使用@RestController或@Controller注解来标识。在Spring Boot中,对Controller层进行单元测试,可以使用@WebMvcTest注解来启动一个轻量级的Spring MVC上下文,只加载Controller层的组件。同时,可以使用@AutoConfigureMockMvc注解来自动配置一个MockMvc对象,用来模拟Http请求和验证Http响应。
例如,假设有一个UserController类,它提供了一个根据用户ID查询用户信息的接口:
@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public ResponseEntity<User> getUserById(@PathVariable Long id) {User user = userService.getUserById(id);if (user == null) {return ResponseEntity.notFound().build();} else {return ResponseEntity.ok(user);}}
}
要对这个类进行单元测试,可以编写以下测试类:
@WebMvcTest(UserController.class)
@AutoConfigureMockMvc
public class UserControllerTest {@Autowiredprivate MockMvc mockMvc;@MockBeanprivate UserService userService;@Testpublic void testGetUserById() throws Exception {// 创建一个User对象User user = new User();user.setId(1L);user.setName("Alice");user.setEmail("alice@example.com");// 当调用userService.getUserById(1L)时,返回user对象when(userService.getUserById(1L)).thenReturn(user);// 模拟发送GET请求到/users/1,并验证响应状态码为200,响应内容为JSON格式的user对象mockMvc.perform(get("/users/1")).andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON)).andExpect(jsonPath("$.id").value(1L)).andExpect(jsonPath("$.name").value("Alice")).andExpect(jsonPath("$.email").value("alice@example.com"));// 验证userService.getUserById(1L)方法被调用了一次verify(userService, times(1)).getUserById(1L);}
}
在这个测试类中,使用了以下几个关键点和技巧:
- 使用@WebMvcTest(UserController.class)注解表示只加载UserController类的组件,不加载其他层次的组件。
- 使用@AutoConfigureMockMvc注解表示自动配置一个MockMvc对象,并使用@Autowired注解将其注入到测试类中。
- 使用@MockBean注解表示创建一个UserService的Mock对象,并使用@Autowired注解将其注入到测试类中。这样可以避免真实地调用UserService的方法,而是模拟其行为。
- 使用when方法来定义Mock对象的行为,例如当调用userService.getUserById(1L)时,返回user对象。
- 使用mockMvc.perform方法来模拟发送Http请求,并使用andExpect方法来验证Http响应。可以使用多种匹配器来验证响应状态码、内容类型、内容值等。
- 使用verify方法来验证Mock对象的方法是否被调用了指定次数。
Repository层
Repository层是指封装数据访问和持久化的层,它通常使用@Repository或@JpaRepository注解来标识。在Spring Boot中,对Repository层进行单元测试,可以使用@DataJpaTest注解来启动一个嵌入式数据库,并自动配置JPA相关的组件。同时,可以使用@TestEntityManager注解来获取一个TestEntityManager对象,用来操作和验证数据库数据。
例如,假设有一个UserRepository接口,它继承了JpaRepository接口,并提供了一个根据用户姓名查询用户列表的方法:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {List<User> findByName(String name);
}
要对这个接口进行单元测试,可以编写以下测试类:
@DataJpaTest
public class UserRepositoryTest {@Autowiredprivate UserRepository userRepository;@Autowiredprivate TestEntityManager testEntityManager;@Testpublic void testFindByName() {// 创建两个User对象,并使用testEntityManager.persist方法将其保存到数据库中User user1 = new User();user1.setName("Bob");user1.setEmail("bob@example.com");testEntityManager.persist(user1);User user2 = new User();user2.setName("Bob");user2.setEmail("bob2@example.com");testEntityManager.persist(user2);// 调用userRepository.findByName方法,传入"Bob"作为参数,得到一个用户列表List<User> users = userRepository.findByName("Bob");// 验证用户列表的大小为2,且包含了user1和user2assertThat(users).hasSize(2);assertThat(users).contains(user1, user2);}
}
在这个测试类中,使用了以下几个关键点和技巧:
- 使用@DataJpaTest注解表示启动一个嵌入式数据库,并自动配置JPA相关的组件。这样可以避免依赖外部数据库,而是使用内存数据库进行测试。
- 使用@Autowired注解将UserRepository和TestEntityManager对象注入到测试类中。
- 使用testEntityManager.persist方法将User对象保存到数据库中。这样可以准备好测试数据,而不需要手动插入数据。
- 使用userRepository.findByName方法调用自定义的查询方法,得到一个用户列表。
- 使用AssertJ的断言语法来验证用户列表的大小和内容。可以使用多种条件和匹配器来验证结果。
三、Spring Boot中Mock对象的使用
在Spring Boot中,除了使用@WebMvcTest和@DataJpaTest等注解来加载特定层次的组件外,还可以使用@SpringBootTest注解来加载完整的Spring上下文,从而进行更加集成的测试。但是,在这种情况下,可能会遇到一些问题,例如:
- 测试过程中需要依赖外部资源,如数据库、消息队列、Web服务等。这些资源可能不稳定或不可用,导致测试失败或超时。
- 测试过程中需要调用其他组件或服务的方法,但是这些方法的实现或行为不确定或不可控,导致测试结果不可预测或不准确。
- 测试过程中需要验证一些难以观察或测量的结果,如日志输出、异常抛出、私有变量值等。这些结果可能需要使用复杂或侵入式的方式来获取或验证。
为了解决这些问题,可以使用Mock对象来模拟真实对象行为。Mock对象是指在测试过程中替代真实对象的虚拟对象,它可以根据预设的规则来返回特定的值或执行特定的操作。使用Mock对象有以下好处:
- 降低测试依赖:通过使用Mock对象来替代外部资源或其他组件,可以减少测试过程中对真实环境的依赖,使得测试更加稳定和可靠。
- 提高测试控制:通过使用Mock对象来模拟特定的行为或场景,可以提高测试过程中对真实对象行为的控制,使得测试更加灵活和精确。
- 简化测试验证:通过使用Mock对象来返回特定的结果或触发特定的事件,可以简化测试过程中对真实对象结果或事件的验证,使得测试更加简单和直观。
在Spring Boot中,要使用Mock对象,可以使用@MockBean注解来创建和注入一个Mock对象。这个注解会自动使用Mockito库来创建一个Mock对象,并将其添加到Spring上下文中。同时,可以使用when方法来定义Mock对象的行为,以及verify方法来验证Mock对象的方法调用。
例如,假设有一个EmailService接口,它提供了一个发送邮件的方法:
public interface EmailService {void sendEmail(String to, String subject, String content);
}
要对这个接口进行单元测试,可以编写以下测试类:
@SpringBootTest
public class EmailServiceTest {@Autowiredprivate UserService userService;@MockBeanprivate EmailService emailService;@Testpublic void testSendEmail() {// 创建一个User对象User user = new User();user.setId(1L);user.setName("Alice");user.setEmail("alice@example.com");// 当调用emailService.sendEmail方法时,什么也不做doNothing().when(emailService).sendEmail(anyString(), anyString(), anyString());// 调用userService.sendWelcomeEmail方法,传入user对象作为参数userService.sendWelcomeEmail(user);// 验证emailService.sendEmail方法被调用了一次,并且参数分别为user.getEmail()、"Welcome"、"Hello, Alice"verify(emailService, times(1)).sendEmail(user.getEmail(), "Welcome", "Hello, Alice");}
}
在这个测试类中,使用了以下几个关键点和技巧:
- 使用@SpringBootTest注解表示加载完整的Spring上下文,并使用@Autowired注解将UserService对象注入到测试类中。
- 使用@MockBean注解表示创建一个EmailService的Mock对象,并使用@Autowired注解将其注入到测试类中。这样可以避免真实地调用EmailService的方法,而是模拟其行为。
- 使用doNothing方法来定义Mock对象的行为,例如当调用emailService.sendEmail方法时,什么也不做。也可以使用doReturn、doThrow、doAnswer等方法来定义其他类型的行为。
- 使用anyString方法来表示任意字符串类型的参数。也可以使用anyInt、anyLong、anyObject等方法来表示其他类型的参数。
- 使用userService.sendWelcomeEmail方法调用被测方法,传入user对象作为参数。
- 使用verify方法来验证Mock对象的方法是否被调用了指定次数,并且参数是否符合预期。也可以使用never、atLeast、atMost等方法来表示其他次数的验证。
除了使用@MockBean注解来创建和注入Mock对象外,还可以使用@SpyBean注解来创建和注入Spy对象。Spy对象是指在测试过程中部分替代真实对象的虚拟对象,它可以根据预设的规则来返回特定的值或执行特定的操作,同时保留真实对象的其他行为。使用Spy对象有以下好处:
- 保留真实行为:通过使用Spy对象来替代真实对象,可以保留真实对象的其他行为,使得测试更加接近真实环境。
- 修改部分行为:通过使用Spy对象来模拟特定的行为或场景,可以修改真实对象的部分行为,使得测试更加灵活和精确。
- 观察真实结果:通过使用Spy对象来返回特定的结果或触发特定的事件,可以观察真实对象的结果或事件,使得测试更加直观和可信。
在Spring Boot中,要使用Spy对象,可以使用@SpyBean注解来创建和注入一个Spy对象。这个注解会自动使用Mockito库来创建一个Spy对象,并将其添加到Spring上下文中。同时,可以使用when方法来定义Spy对象的行为,以及verify方法来验证Spy对象的方法调用。
例如,假设有一个LogService接口,它提供了一个记录日志的方法:
public interface LogService {void log(String message);
}
要对这个接口进行单元测试,可以编写以下测试类:
@SpringBootTest
public class LogServiceTest {@Autowiredprivate UserService userService;@SpyBeanprivate LogService logService;@Testpublic void testLog() {// 创建一个User对象User user = new User();user.setId(1L);user.setName("Alice");user.setEmail("alice@example.com");// 当调用logService.log方法时,调用真实的方法,并打印参数到控制台doAnswer(invocation -> {String message = invocation.getArgument(0);System.out.println(message);invocation.callRealMethod();return null;}).when(logService).log(anyString());// 调用userService.createUser方法,传入user对象作为参数userService.createUser(user);// 验证logService.log方法被调用了两次,并且参数分别为"Creating user: Alice"、"User created: Alice"verify(logService, times(2)).log(anyString());verify(logService, times(1)).log("Creating user: Alice");verify(logService, times(1)).log("User created: Alice");}
}
在这个测试类中,使用了以下几个关键点和技巧:
- 使用@SpringBootTest注解表示加载完整的Spring上下文,并使用@Autowired注解将UserService对象注入到测试类中。
- 使用@SpyBean注解表示创建一个LogService的Spy对象,并使用@Autowired注解将其注入到测试类中。这样可以保留LogService的真实行为,同时修改部分行为。
- 使用doAnswer方法来定义Spy对象的行为,例如当调用logService.log方法时,调用真实的方法,并打印参数到控制台。也可以使用doReturn、doThrow、doNothing等方法来定义其他类型的行为。
- 使用anyString方法来表示任意字符串类型的参数。也可以使用anyInt、anyLong、anyObject等方法来表示其他类型的参数。
- 使用userService.createUser方法调用被测方法,传入user对象作为参数。
- 使用verify方法来验证Spy对象的方法是否被调用了指定次数,并且参数是否符合预期。也可以使用never、atLeast、atMost等方法来表示其他次数的验证。
总结
本文介绍了如何在Spring Boot中编写优雅的单元测试,包括如何添加单元测试依赖,如何对不同层次的组件进行单元测试,以及如何使用Mock对象和Spy对象来模拟真实对象行为。本文还给出了每种类型的单元测试的示例代码,并解释了其中的关键点和技巧。
通过编写单元测试,可以提高Spring Boot应用的质量和稳定性,同时也可以提高开发者的编程水平和信心。希望本文能够对你有所帮助和启发,让你能够在Spring Boot中编写优雅的单元测试。
相关文章:
Spring Boot中如何编写优雅的单元测试
单元测试是指对软件中的最小可测试单元进行检查和验证。在Java中,单元测试的最小单元是类。通过编写针对类或方法的小段代码,来检验被测代码是否符合预期结果或行为。执行单元测试可以帮助开发者验证代码是否正确实现了功能需求,以及是否能够…...
三星Galaxy S23与iPhone 15的对比分析:谁会胜出?
三星Galaxy S23与iPhone 15的对决将于下个月进入高潮,这将是今年智能手机中最大的一场较量。毕竟,这是两家领先的移动设备制造商的旗舰手机。他们的手机的比较将在很大程度上决定谁能获得最佳手机的称号。 我们已经知道有利于三星Galaxy S23的情况,该产品自春季以来一直在推…...
MySQL索引 事物 存储引擎
一 索引 索引的概念 索引就是一种帮助系统能够更快速的查找信息的结构 索引的作用 索引的副作用 创建索引的规则 MySQL的优化 哪些字段/场景适合创建索引 哪些不适合 小字段唯一性强的字段更新不频繁,但查询率比较高的字段表记录超过 300行主键,外键…...
【谷粒学院】报错记录
无法从Nacos获取动态配置 原先gulimall-common中SpringCloud Alibaba的版本是2.1.0.RELEASE,无法从Nacos中获取配置文件信息 <dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId&…...
微积分基本概念
微分 函数的微分是指对函数的局部变化的一种线性描述。微分可以近似地描述当函数自变量的取值作足够小的改变时,函数的值是怎样改变的。。对于函数 y f ( x ) y f(x) yf(x) 的微分记作: d y f ′ ( x ) d x d_y f^{}(x)d_x dyf′(x)dx 微分和…...
【业务功能篇78】微服务-前端后端校验- 统一异常处理-JSR-303-validation注解
5. 前端校验 我们在前端提交的表单数据,我们也是需要对提交的数据做相关的校验的 Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可 校验的页面效果 前端数据…...
pytorch的用法
...
Qt 设置窗口背景
窗口背景无非两种:背景色、背景图片。Qt中窗口背景如何设置? 一、QPalette设置背景 二、实现paintEvent,使用QPainter来绘制背景 三、使用QSS来设置背景 关于QSS的使用不想多说,一般我不用QSS设置窗口背景,也不建议…...
大模型是什么?泰迪大模型能够解决企业哪些痛点?
什么是大模型? 大模型是指模型具有庞大的参数规模和复杂程度的机器学习模型。在深度学习领域,大模型通常是指具有数百万到数十亿参数的神经网络模型。这些模型需要大量的计算资源和存储空间来训练和存储,并且往往需要进行分布式计算和特殊…...
YOLOv7-tracker 目标追踪 输入视频帧
目录 1 项目安装1.1 环境搭建1.2 项目下载1.3 权重下载1.4 环境安装1.5 上传待检测的视频帧 2 视频帧检测与追踪2.1 检测与追踪2.3 结果 参考项目:https://github.com/JackWoo0831/Yolov7-tracker/tree/master github链接:https://github.com/Whiffe/Yo…...
C语言二——C语言编写一段代码,求一元二次方程的根
这段代码实现了解一元二次方程的根的计算。用户需要输入方程的系数a、b、c,然后根据判别式的值确定方程的根的情况,并进行相应的输出。 如果判别式大于0,说明方程有两个实根,分别计算并输出。如果判别式等于0,说明方程…...
用Idea把SpringBoot项目打包镜像上传至docker
1、设置docker把2375端口开起来 命令查看docker装在哪里 vim docker.service 新增 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock 2、配置Dockerfile 我在跟pom同一层 3、配置docker-maven-plugin <plugin><groupId>com.spotify</groupId><arti…...
基于 SVG 的图形交互方案实践
不知道从什么时候起,人们开始喜欢上数字大屏这种“花里胡哨”的东西,仿佛只要用上“科技蓝”这样神奇的色调,就可以让一家公司焕然一新,瞬间变得科技感满满。不管数字大屏的实际意义,是用来帮助企业监控和决策…...
微服务(rpc)
微服务(rpc) 微服务必备的模块生产者消费者管理平台流量控制集群情况下如何做到流量监控 负载均衡服务发现和治理序列化传输序列化和反序列化 微服务是一种架构风格,将一个应用程序拆分为一组小型、独立的服务,每个服务都可以独立…...
ThinkPHP 多应用配置,及不同域名访问不同应用的配置【详解】
ThinkPHP 多应用配置,及不同域名访问不同应用的配置【详解】 一、安装多应用扩展二、删除项目的中默认的controller文件夹三、创建多应用四、修改config/app.php文件五、测试并且访问多应用六、配置小皮,不同域名访问不同的应用七、小结 一、安装多应用扩…...
Springboot+Mybatis框架是否会取代SSM框架?
个人认真思考的观点:从市场使用来说,会有这个趋势。从技术上来说,不存在被替代这一说。 Spring BootMybatis框架是指使用Spring Boot作为基础框架,并集成Mybatis作为持久层框架的组合,它是一个基于Spring框架的快速开发…...
使用windeployqt和InstallShield打包发布Qt软件的流程
前言 Qt编译之后需要打包发布,并且发布给用户后需要增加一个安装软件,通过安装软件可以实现Qt软件的安装;用于安装软件的软件有很多,这里主要介绍InstallShield使用的流程; 使用windeployqt打包Qt编译后的程序 Qt程序…...
解决selenium的getdrive()方法阻塞问题
selenium里面的Webdriver的get()方法默认是阻塞的,也就是说要等整个页面全都加载完它才会相应。但我们大部分时候不需要用到页面里的所有东西,也许只需要用到里面的一个元素就行了 所以下面是我的解决方法: 初始化代码: # 设置…...
js的闭包
闭包是有权限访问其他函数作用域的局部变量的一个函数 代码 function outer(){const a1;function f(){console.log(a)}f()}outer() 简单来说:闭包内层函数引用的外层函数变量 为什么要使用闭包? 用此方法可以来统计函数调用次数, 但是如…...
ubuntu20.04 直接安装vpp23.06 测试双 VPP Tunnel Ike2
环境信息:VMware Workstation 17 Pro ubuntu20.04 (清华源) ubuntu 源点进去选:ubuntu-22.04.3-desktop-amd64.iso 如果之前装过VPP,用以下命令确定是否卸载干净: dpkg -l | grep vpp dpkg -l | grep DPDK 卸载: …...
mysql sql 执行流程
监控查询缓存的命中率 show status like ‘%qcache%’; mysql 缓存机制,以及 8.0 为啥取消 select sql_NO_Cache * from 表 where xxx; # 不使用缓存...
go-kafka
go kafka包 本文使用的是kafka-go 6.5k 这个包 其他包参考: 我们在细分市场中非常依赖GO和Kafka。不幸的是,在撰写本文时,Kafka的GO客户库的状态并不理想。可用选项是: 萨拉玛(Sarama) 10k,这…...
如何在windows电脑上安装多个node,并可以进行随意切换
一、进入官网http://nvm.uihtm.com/ 下载 二、启动解压后的程序 1.开始安装nvm 选择要安装的目录 一直下一步–下一步–最后点击完成 3.最后点击完成即可 ![在这里插入图片描述](https://img-blog.csdnimg.cn/3656568c7e9946e8a04219811fc4c4d3.png 三、在cmd控制台进行操作…...
《机器学习核心技术》分类算法 - 决策树
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 决策树 1、决策树API2、决策时实际应用2.1、获取数据集2.2、划分数据集2.3、决策…...
aws PinPoint发附件demo
php 版aws PinPoint发附件demo Laravel8框架,安装了"aws/aws-sdk-php": "^3.257" 主要代码: public function sendRawMail(Request $request) {$file $request->file(attachment);/*echo count($file);dd($file);*/$filenam…...
边写代码边学习之Bidirectional LSTM
1. 什么是Bidirectional LSTM 双向 LSTM (BiLSTM) 是一种主要用于自然语言处理的循环神经网络。 与标准 LSTM 不同,输入是双向流动的,并且它能够利用双方的信息。 它也是一个强大的工具,可以在序列的两个方向上对单词和短语之间的顺序依赖…...
Django学习笔记-实现联机对战
笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。 CONTENTS 1. 统一长度单位2. 增加联机对战模式3. 配置Django Channels 1. 统一长度单位 多人模式中每个玩家所看到的地图相对来说应该是一样的,因此需要固定地…...
nacos总结1
5.Nacos注册中心 国内公司一般都推崇阿里巴巴的技术,比如注册中心,SpringCloudAlibaba也推出了一个名为Nacos的注册中心。 5.1.认识和安装Nacos Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,…...
Web安全测试(三):SQL注入漏洞
一、前言 结合内部资料,与安全渗透部门同事合力整理的安全测试相关资料教程,全方位涵盖电商、支付、金融、网络、数据库等领域的安全测试,覆盖Web、APP、中间件、内外网、Linux、Windows多个平台。学完后一定能成为安全大佬! 全部…...
Webstorm 入门级玩转uni-app 项目-微信小程序+移动端项目方案
1. Webstorm uni-app语法插件 : Uniapp Support Uniapp Support - IntelliJ IDEs Plugin | Marketplace 第一个是不收费,第二个收费 我选择了第二个Uniapp Support ,有试用30天,安装重启webstorm之后,可以提高生产率…...
wordpress menu插件/长沙关键词优化公司电话
这是一篇讨论Node.js在无需修改任何代码从单核垂直扩展到多核,再水平扩展到多台集群和消息集成的分布式系统,展示了Node.JS在无缝扩展性方面要强于Java。其主要架构是Node.js微服务 消息Messaging 集群Clustering 。翻译如下: 当使用微服务…...
北京建设安全网络平台87/如何优化标题关键词
目前对消息队列并不了解其原理,本篇文章主要是通过慕课网学习归纳的一些笔记,为后续学习打下基础。 众所周知在对网站设计的时候,会遇到给用户“群发短信”,“订单系统有大量的日志”,“秒杀设计”等,服务器…...
公司网站建设设计公司排名/数据分析平台
截取第三个/后的字符串方法://先使用spilt按/分割符 分割字符串 成数组aa"/a1Wsm6EWNcQ/${deviceName}/user/topicname2";var bb new Array();bb aa.split("/");var ccbb.slice(3);console.log(cc); //cc 为["user", "topicnam…...
网站策划书格式/郑州客串seo
前言 cloudflare 是一家国外的 CDN 加速服务商,还是很有名气的。提供免费和付费的加速和网站保护服务。以前推荐过的百度云加速的国外节点就是和 cloudflare 合作使用的 cloudflare 的节点。 cloudflare 提供了不同类型的套餐,即使是免费用户,…...
北京出名做网站的公司/东莞网站制作
1.概率图模型简介: 概率图模型是图灵奖获得者Pearl开发出来的用图来表示变量概率依赖关系的理论。概率图模型理论分为概率图模型表示理论,概率图模型推理理论和概率图模型学习理论。 概率图理论共分为三个部分,分别为概率图模型表示理论&…...
龙岗网站推广/永久免费制作网页
我这个菜鸟真的弱爆了~~弱爆了~~以前竟然在写着超级垃圾的快速幂,彻底服了自己~~无语~~实在无语 program1(弱智快速幂取模) 图1:猴子爬下去: 图2:猴子很老实滴爬回来 #include<iostream> using namespace std; //求2^N%20…...