超详细 springboot 整合 Mock 进行单元测试!本文带你搞清楚!

文章目录

  • 一、什么是Mock
    • 1、Mock定义
    • 2、为什么使用
    • 3、常用的Mock技术
    • 4、Mokito中文文档
    • 5、集成测试和单元测试区别
  • 二、API
    • 1、Mockito的API
    • 2、ArgumentMatchers参数匹配
    • 3、OngoingStubbing返回操作
  • 三、Mockito的使用
    • 1、添加Maven依赖
    • 2、@InjectMocks、@Mock使用
    • 3、SpringbootTest 注解和 RunWith 注解在测试类的作用
  • 四、Mock 测试代码案例
    • 1、添加依赖
    • 2、编写业务代码
    • 3、Mock 测试
      • (1)常规测试
      • (2)Mock 测试
      • (3)Mock 测试常用方法
        • thenReturn 系列方法
        • thenThrow 系列方法
        • verify 系列方法
        • 模拟对象有两种方式
        • 对 void 的方法设置模拟
      • (4)Mock 测试常用注解
    • 五、Mock 测试结合 Java 反射综合案例

一、什么是Mock

1、Mock定义

Mockito是Java单元测试开发框架。在写测试单元时它可以MockMock的中文释义是模拟,所以Mockito从名字上可以看出是要模拟一种场景)。

它可以模拟任何 Spring 管理的 Bean、模拟方法的返回值、模拟抛出异常等,避免为了测试一个方法,却要自行构建整个 bean 的依赖链。

Mock 测试主要是用来进行开发中一些 未完成的接口 或者 网络断开数据库连接错误 等方法调用。

举个例子:

如下代码所示,list 集合需要从数据库查询出来。但是如果暂时数据库不能用,有需要测试,这个时候就可以进行 Mock 模拟出符合条件的 list 集合进行本地测试,无需连接数据库。

在这里插入图片描述

2、为什么使用

在对代码进行单元测试过程中,经常会有以下的情况发生:

class A 依赖 class B  
class B 依赖 class C和class D  
class C 依赖 ...  
class D 依赖 ...  

1.被测对象依赖的对象构造复杂
我们想对class A进行单元测试,需要构造大量的class B、C、D等依赖造步骤多、耗时较长的对象,
对于他们的构造我们可以利用mock去构造过程复杂的对象用于class A的测试,
因为我们只是想测试class A的行为是否符合预期,我们并不需要测试依赖对象。

2.被测单元依赖的模块尚未开发完成,而被测对象需要依赖模块的返回值进行测试:
----- 比如service层的代码中,包含对dao层的调用,但dao层代码尚未实现
----- 比如web的前端依赖后端接口获取数据进行联调测试,但后端接口并未开发完成
----- 比如数据库还不能正常使用但是需要测试功能逻辑是否可行。

3、常用的Mock技术

  • PowerMock
  • EasyMock
  • Mockito
  • JMock

目前在 Java 中主流的 Mock 测试工具有 Mockito、JMock、EasyMock 等等,而 SpringBoot 目前内建的是 Mockito 框架。

4、Mokito中文文档

Mokito中文官网

5、集成测试和单元测试区别

(1)集成测试
测试过程中,会启动整个Spring容器,调用DB 或者 依赖的外部接口等。只不过访问的环境是测试环境。这个过程最大程度还原生产环境过程,但是耗时长。

(2)单元测试
不启动整个应用,只对单个接口/类进行测试。不调用DB 、外部接口,依赖的服务都Mock掉,只测试代码逻辑。这个过程,测试用例耗时短。

二、API

1、Mockito的API

  • mock:构建一个我们需要的对象;可以mock具体的对象,也可以mock接口
  • spy:构建监控对象
  • verify:验证某种行为
  • when:当执行什么操作的时候,一般配合thenXXX 一起使用。表示执行了一个操作之后产生什么效果
  • doReturn:返回什么结果
  • doThrow:抛出一个指定异常
  • doAnswer:做一个什么相应,需要我们自定义Answer
  • times:某个操作执行了多少次
  • atLeastOnce:某个操作至少执行一次
  • atLeast:某个操作至少执行指定次数
  • atMost:某个操作至多执行指定次数
  • atMostOnce:某个操作至多执行一次
  • doNothing:不做任何处理
  • doReturn:返回一个结果
  • doThrow:抛出一个指定异常
  • doAnswer:指定一个操作,传入Answer
  • doCallRealMethod:返回真实业务执行的结果,只能用于监控对象

2、ArgumentMatchers参数匹配

  • anyInt:任何int类型的参数,类似的还有anyLong/anyByte等等。
  • eq:等于某个值的时候,如果是对象类型的,则看toString方法
  • isA:匹配某种类型
  • matches:使用正则表达式进行匹配

3、OngoingStubbing返回操作

  • thenReturn:指定一个返回的值
  • thenThrow:抛出一个指定异常
  • then:指定一个操作,需要传入自定义Answer
  • thenCallRealMethod:返回真实业务执行的结果,只能用于监控对象

三、Mockito的使用

1、添加Maven依赖

  • Java 环境依赖
<!--		https://mvnrepository.com/search?q=Mockito-->
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>4.4.0</version>
</dependency>
  • SpringBoot 环境依赖

注意:SpringBoot 默认的 Mock 框架是 Mockito,和 junit 一样,只需要依赖 spring-boot-starter-test 就可以了

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

2、@InjectMocks、@Mock使用

  • @Mock: 用于代替Mockito.mock创建mock对象,创建一个Mock实例,需要基于JUnit5环境。
  • @InjectMocks: 创建一个实例,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中

直白的理解就是:

如图,实体类TUserServiceImpl通过注解 @Autowired注入了三个实体:TUserMapper、JdbcTemplate 和 NamedParameterJdbcTemplate。
在这里插入图片描述
如果想要测试TUserServiceImpl,那么test中,TUserMapper、JdbcTemplate 和 NamedParameterJdbcTemplate就要用@Mock注解创建Mock实例,而要被测试TUserServiceImpl就要用@InjectMocks注解创建实例,这个时候被@Mock注解创建的TUserMapper、JdbcTemplate 和 NamedParameterJdbcTemplate就被注入到通过 @InjectMocks注解创建的TUserServiceImpl实例中。如下图所示:
在这里插入图片描述

最后的大白话解释 !!!

你要测试哪个类(如TUserServiceImpl),那么就用 @InjectMocks注解;
被测试的类中通过 @Autowired注解注入了几个,那么测试类里面就用@Mock注解创建几个实例!

使用Mockito的注解,需要让注解生效,让注解生效的方法有两个:

  1. 给被测类添加 @RunWith(MockitoJUnitRunner.class) 或者 @RunWith(SpringJUnit4ClassRunner.class) 注解
@RunWith(MockitoJUnitRunner.class)
public class MockitoAnnotationTest {
    ...
}
  1. 在初始化方法中使用MockitoAnnotations.openMocks(this)
@Before
public void init() {
    MockitoAnnotations.openMocks(this);
}

注意:新版spring-boot-starter-test不再集成junit,而是junit-jupiter,找不到@RunWith注解:

  • spring-boot-starter-test 2.5.5 版本只需要在类上加上@SpringBootTest即可,不需要再加@RunWith()注解了。
  • spring-boot-starter-test 2.4.x 版本的也没有@RunWith()注解,至于从哪个版本开始没有@RunWith()注解的,请自行查阅相关文档。
  • 一些较低版本也没有 openMocks 方法,而是 initMocks

3、SpringbootTest 注解和 RunWith 注解在测试类的作用

  • @SpringbootTest

这个注解相当于启动类的作用,加了这个注解后,当使用加了@Test注解的方法时,会加载Spring上下文,跟SpringbootApplication这个启动类一样,把bean加载进IOC容器。

其中参数classes 需指明启动类.class,如果不指明,需要保证启动类所在的包和加了SpringbootTest注解的类 在同一个包或者是启动类的子包下,否则注入到( @Autowired / @Resource)会报空指针异常。如下:

@SpringBootTest(classes = MySpringbootApplication.class)
  • @RunWith

@RunWith(SpringRunner.class),作用是与Spring环境整合,因为在测试类中我们可以需要用@Autowired自动装配IOC容器中的bean,所以需要与Spring环境进行整合,才能实现自动装配,否则会装配失败,导致bean为null。

有时候会发现,有的测试类不添加@RunWith也能注入成功,这是因为,如果导入@Test注解的包是org.junit.jupiter.api.Test,则不需要添加@RunWith注解,如果导入的是org.junit.Test,则需要添加,这点需要注意。

四、Mock 测试代码案例

1、添加依赖

 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

注意:本案例用的 springboot 版本是 2.6 版本

在这里插入图片描述

2、编写业务代码

@Service
public class PositionService {

    public String getStr(String str){
        return str;
    }
 
 	
 	public void getVoid(){
        System.out.println("没有返回值");
    }
    
}

3、Mock 测试

(1)常规测试

先不使用 Mockito ,而是真的去调用一个正常的 Spring bean ,测试类写法如下。其实就是很普通的注入 PositionService bean,然后去调用他的方法。

测试代码:

注意:

可以看到测试类中引用的包是 org.junit.jupiter.api.Testorg.junit.jupiter.api.BeforeEach,是 jupiter.api 包下面的,此时测试类只用了 @SpringBootTest 这一个注解;

但是,如果用的是 org.junit.Testorg.junit.Before,测试类上面必须同时用 @RunWith(SpringRunner.class)@SpringBootTest(classes = MySpringbootApplication.class)必须同时用!!!!!

import com.cyd.applicationstartup.MySpringbootApplication;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;



@SpringBootTest(classes = MySpringbootApplication.class)
public class PositionServiceTest {

    @Autowired
    private PositionService positionService;

    @BeforeEach
    public void init() {
    
    	// 对所有注解了@Mock的对象进行模拟
        MockitoAnnotations.openMocks(this);
        System.out.println("初始化方法");
    }

    @Test
    public void testGetStr() {

        String str = positionService.getStr("刘亦菲");
        System.out.println("测试结果:" + str);

    }
}

测试结果:

在这里插入图片描述

(2)Mock 测试

Mock 测试需要自定返回结果,结果和方法返回结果类型一致。

语法如下:

Mockito.when( 对象.方法名() ).thenReturn( 自定义结果 )

使用 Mockito 模拟 Bean 的单元测试代码示例如下:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest(classes = MySpringbootApplication.class)
public class PositionServiceTest {

    @Mock
    private PositionService positionService;

    @BeforeEach
    public void init() {
        System.out.println("初始化方法");
    }

    @Test
    public void testMockGetStr() {
        // 定义当调用mock positionService 的 getStr() 方法,并且任意字符串参数时,就返回字符串 "刘亦菲"
        Mockito.when(positionService.getStr(Mockito.anyString())).thenReturn("刘亦菲");

        // 定义当调用 mock positionService 的 getStr() 方法,并且参数是字符串 "美女" 时,就返回字符串 "刘亦菲"
        Mockito.when(positionService.getStr("美女")).thenReturn("刘亦菲");
        System.out.println(positionService.getStr("美女"));

        // 验证 positionService 的 getStr()这个方法是否被调用过
        Mockito.verify(positionService).getStr("刘亦菲");
    }
}

注意:
代码中第一个 Mockito.when 的参数用的是 Mockito.anyString(),表示 任意字符串参数调用 getStr() 方法,就会返回字符串 “刘亦菲”;
第二个 Mockito.when 的参数用的是字符串"美女",表示限制只有当参数是 "美女"时,才会返回 “刘亦菲”。
因此,在日常 Mock 测试中,通常使用 Mockito.any 作为参数。

(3)Mock 测试常用方法

thenReturn 系列方法

① 定义当调用mock positionService 的 getStr() 方法,并且任意字符串参数时,就返回字符串 “哈哈哈哈”:

Mockito.when(positionService.getStr(Mockito.anyString())).thenReturn("哈哈哈哈");
System.out.println(positionService.getStr("任意参数"));

表示任意值的参数如下图:

在这里插入图片描述

② 定义当调用 mock positionService 的 getStr() 方法,并且限制参数只有是字符串 “美女” 时,才返回字符串 “刘亦菲”:

Mockito.when(positionService.getStr("美女")).thenReturn("刘亦菲");
System.out.println(positionService.getStr("美女"));
thenThrow 系列方法

① 当调用 mock positionService 的 getStr() 方法,输入的的参数是 字符串 “9” 时,抛出一个 RuntimeException:

Mockito.when(positionService.getStr("9")).thenThrow(new RuntimeException("mock throw exception"));
String str = positionService.getStr("9"); //会抛出一个RuntimeExceptio

测试结果:

在这里插入图片描述
② 如果方法没有返回值的话(即是方法定义为 public void myMethod() {…}),要改用 doThrow() 抛出 Exception:

Mockito.doThrow(new RuntimeException("mock throw exception when method is void")).when(positionService).getVoid();
positionService.getVoid(); //会抛出一个RuntimeException

测试结果:

在这里插入图片描述

verify 系列方法

① 检查调用 positionService 的 getStr() 方法,、且参数为 “3” 的次数是否为1次:

Mockito.verify(positionService, Mockito.times(1)).getStr(Mockito.eq("3"));

② 验证调用顺序,验证 positionService 是否先调用 getStr() 两次,并且第一次的参数是 “3”、第二次的参数是 “5”,然后才调用 getVoid() 方法:

InOrder inOrder = Mockito.inOrder(positionService);
inOrder.verify(positionService).getStr("3");
inOrder.verify(positionService).getStr("5");
inOrder.verify(positionService).getVoid();
模拟对象有两种方式
  1. 对注解了 @Mock 的对象进行模拟 MockitoAnnotations.openMocks(this);
  2. 对单个对象手动 mock :xxx= Mockito.mock(xxx.class);
对 void 的方法设置模拟

positionService 中有如下方法:

public void getVoidWithParam(String param){
        System.out.println("没有返回值");
    }

Mock 测试方法:

		/*对void的方法设置模拟*/
        Mockito.doAnswer(invocationOnMock -> {
            System.out.println("进入了Mock");
            return null;
        }).when(positionService).getVoidWithParam("param");

(4)Mock 测试常用注解

  • 全部 Mock
@Mock
private ServiceA serviceA;

这种方式,serviceA中的所有方法都会被mock,并不会真正被调用到

  • 依赖注入

ServiceA 依赖了 ServiceC 和 DaoA,使用InjectMocks可以自动注入。

@InjectMocks
private ServiceA serviceA;
  • 真实调用
@Spy
private ServiceC serviceC;

这种方式,调用serviceC的方法,会被真实调用。

五、Mock 测试结合 Java 反射综合案例

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;


@RunWith(MockitoJUnitRunner.class)
public class MyMockServiceTest {

   
    @Mock
    private CustomerDao             customerDao;

    @Mock
    private MockDaoA     			mockDaoA;

    @Mock
    private MockDaoC   				mockDaoC;

    @Mock
    private MockDaoD        		mockDaoD;

    @Mock
    private MockDaoE         		mockDaoE;

    @InjectMocks
    MyMockService          			myMockService;

    MockTestDataDto                 mockTestDataDto;

    @Before
    public void init() {

        //        Apollo 配置
        ReflectionTestUtils.setField(myMockService, "mockValue", "58699DFR-1456984524");

        MockitoAnnotations.initMocks(this);

        mockTestDataDto = new MockTestDataDto();
        mockTestDataDto.setCallback("callback");

        PolicyRelatedInfo policyRelatedInfo = new PolicyRelatedInfo();
        policyRelatedInfo.setRelationToAppnt("1");
        Mockito.when(mockDaoA.selectRelationByParams(Mockito.any()))
                .thenReturn(policyRelatedInfo);

        Customer customer = new Customer();
        insu.setPhone("4654");
        insu.setSex("1");
        insu.setIdType("1");
        insu.setIdNo("1");
        insu.setName("张三");
        insu.setBirthday(new Date());
        Mockito.when(customerDao.selectByPrimaryKey(Mockito.anyInt())).thenReturn(customer);

    }

    
    @Test
    public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException, InstantiationException {

        ArrayList<PolicyDanger> getPolicyDangerList = new ArrayList<>();

        
        PolicyDanger policyDanger1 = new PolicyDanger();
        policyDanger1.setIsPassFlag("M");
        policyDanger1.setDanderCode("595648FD");
        policyDanger1.setTotalAmnt(new BigDecimal(100.1223));
        

       
        PolicyDanger policyDanger2 = new PolicyDanger();
        policyDanger2.setIsPassFlag("M");
        policyDanger2.setDanderCode("595648FD");
        policyDanger2.setTotalAmnt(new BigDecimal(100.1223));

        getPolicyDangerList.add(policyDanger1);
        getPolicyDangerList.add(policyDanger2);
        Mockito.when(mockDaoC.selectPolicyDangerList(Mockito.any())).thenReturn(getPolicyDangerList);

        ArrayList<Province> provinceList = new ArrayList<>();

        Province province  = new Province();
        province.setProvinceCode("5894");
        province.setDutyCode("5928D2");
        provinceList.add(province);
        Mockito.when(mockDaoD.selectPolicyByQueryParam(Mockito.any())).thenReturn(provinceList);

        ArrayList<User> userList = new ArrayList<>();
        User user = new User();
        user.setBuyDate(new Date());
        userList.add(user);
        Mockito.when(mockDaoE.selectUserByQueryParam(Mockito.any())).thenReturn(userList);

        //        反射获得类
        MyMockService  hx = new MyMockService();
        Class<? extends MyMockService> cls1 = hx.getClass();

        // 通过指定方法名称和参数类型的方法来获取Method对象(注意: 如果方法名称不存在或参数类型不正确的话,会报错,不会返回null)
        // 注意:这里测试的是 private 修饰的私有方法,需要用 getDeclaredMethod
        // setUserInfo 是需要测试的方法名,后面为该方法需要的参数类型
        Method method = cls1.getDeclaredMethod("setUserInfo", MockTestDataDto.class, Integer.class, String.class,
                SimpleDateFormat.class);
        method.setAccessible(true);

        //        执行方法
        method.invoke(myMockService, mockTestDataDto, 1, "1", new SimpleDateFormat());

    }
}

注意:

如果测试的类中有如下配置:

 @Value("${mock.mapping.name}")
 private String  mockValue;

测试代码中需要如下设置配置值:

 ReflectionTestUtils.setField(mockService, "mockValue", "58699DFR-1456984524");

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Apache Flume事务

Apache Flume 中的事务处理是指 Flume Agent 在处理事件流时的一种机制&#xff0c;用于确保数据的可靠传输和处理。 1. 事务概述&#xff1a; Flume 中的事务是指一组事件的传输和处理&#xff0c;这些事件在传输过程中要么全部成功完成&#xff0c;要么全部失败&#xff0…

Scratch四级:第07讲 编程数学02

第07讲 编程数学02 教练&#xff1a;老马的程序人生 微信&#xff1a;ProgrammingAssistant 博客&#xff1a;https://lsgogroup.blog.csdn.net/ 讲课目录 常考的数学问题项目制作&#xff1a;“求最大公约数”项目制作&#xff1a;“求最小公倍数”项目制作&#xff1a;“早餐…

EasyRecovery数据恢复软件2024最新免费无需激活版下载

EasyRecovery数据恢复软件是一款功能强大、操作简便的数据恢复工具&#xff0c;旨在帮助用户解决各种数据丢失问题。无论是由于误删除、格式化、磁盘损坏还是其他原因导致的数据丢失&#xff0c;EasyRecovery都能提供有效的恢复方案。以下是对EasyRecovery软件功能的详细介绍。…

免疫优化算法(Immune Optimization Algorithm)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 免疫算法是一种模拟生物免疫系统的智能优化算法。想象一下&#xff0c;当我们的身体遇到病毒或细菌侵袭时&#xff0c;免疫系统会启动…

Qt---事件

一、Qt中的事件 鼠标事件 鼠标进入事件enterEvent 鼠标离开事件leaveEvent 鼠标按下mousePressEvent ( QMouseEvent ev) 鼠标释放mouseReleaseEvent 鼠标移动mouseMoveEvent ev->x()&#xff1a;坐标 ev->y()&#xff1a;y坐标 ev->bu…

系统服务(22年国赛)—— Mail邮件服务部署

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 系统服务&#xff08;22年国赛&#xff09;—— Mail邮件服务部署https://myweb.myskillstree.cn/119.html 目录 题目 AppSrv&#xff08;已做好DNS配置&a…

Kotlin: ‘return‘ is not allowed here

报错&#xff1a;以下函数的内部函数return语句报错 Kotlin: return is not allowed here fun testReturn(summary: (String) -> String): String {var msg summary("summary收到参数")println("test内部调用参数&#xff1a;>结果是 &#xff1a;${msg…

Python多线程与互斥锁模拟抢购余票的示例

一、示例代码&#xff1a; from threading import Thread from threading import Lock import timen 100 # 共100张票def task():global nmutex.acquire() # 上锁temp ntime.sleep(0.1)n temp - 1print(购票成…

【计算机毕业设计】基于SSM++jsp的公司员工信息管理系统【源码+lw+部署文档+讲解】

目录 1 绪论 1.1 研究背景 1.2 目的和意义 1.3 论文结构安排 2 相关技术 2.1 SSM框架介绍 2.2 B/S结构介绍 2.3 Mysql数据库介绍 3 系统分析 3.1 系统可行性分析 3.1.1 技术可行性分析 3.1.2 经济可行性分析 3.1.3 运行可行性分析 3.2 系统性能分析 3.2.1 易用性指标 3.2.2 可…

大屏分辨率适配插件v-scale-screen

前言&#xff1a;大屏分辨率适配繁多&#xff0c;目前我认为最简单且问题最少的的方案就是使用v-scale-screen插件&#xff0c;无需考虑单位转换&#xff0c;position定位也正常使用。 1. 效果 填充满屏幕的效果 保持宽高比的效果 2. 插件原理 原理是通过css transfom 实现…

【计算机毕业设计】基于微信小程序的校园二手数码交易平台

随着 计算机技术的成熟&#xff0c;互联网的建立&#xff0c;如今&#xff0c;PC平台上有许多关于校园二手数码交易方面的应用程序&#xff0c;但由于使用时间和地点上的限制&#xff0c;用户在使用上存在着种种不方便&#xff0c;而开发一款基于微信小程序的校园二手数码交易平…

【计算机毕业设计】基于微信小程序的校园综合服务

随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;校园综合服务被用户普遍使用&#xff0c;为方便用户能够可以随时…

深度学习之GAN网络

目录 关于GAN网络 关于生成模型和判别模型 GAN网路的特性和搭建步骤&#xff08;以手写字体识别数据集为例&#xff09; 搭建步骤 特性 GAN的目标函数&#xff08;损失函数&#xff09; 目标函数原理 torch.nn.BCELoss&#xff08;实际应用的损失函数&#xff09; 代码…

IO:线程的同步互斥

一、引入 例&#xff1a; 要求定义一个全局变量 char buf[] "1234567"&#xff0c;创建两个线程&#xff0c;不考虑退出条件。 A线程循环打印buf字符串&#xff0c; B线程循环倒置buf字符串&#xff0c;即buf中本来存储1234567&#xff0c;倒置后buf中存储7654321.…

创新指南|设计冲刺 – 更快找到成功的创新方案

“ 设计冲刺&#xff08;Design Sprint&#xff09;” 一词与跑步无关&#xff0c;而且不局限于设计&#xff0c;它与引导团队加速创新密切相关。设计冲刺旨在帮助创新团队在很短的时间内解决一个极有价值的问题。本文将深入解析这一法宝&#xff1a;设计冲刺是什么&#xff1f…

Electron | 桌面应用的开发神器

初探 Electron 教程将介绍 Electron 打包应用的全过程&#xff0c;从本地测试&#xff0c;打包&#xff0c;到 GitHub 自动化。讲解 Electron Forge 和 Electron Builder 的用法&#xff0c;以及如何在 GitHub Actions 中自动化生成和发布应用。 官方资源 Electron Document…

GDPU unity游戏开发 角色控制器与射线检测

在你的生活中&#xff0c;你一直扮演着你的角色&#xff0c;别被谁控制了。 小试 1. 创建一个角色控制器&#xff0c;通过键盘控制角色控制器的移动&#xff0c;角色控制器与家具发生碰撞后&#xff0c;通过Debug语句打印出被碰撞物体的信息(搜索OnControllerColliderHit的使用…

windows系统安装Ubuntu子系统

安装前先在 控制面板 中打开 程序与功能选项 &#xff0c;点击 启用或关闭Windows功能&#xff1a; 勾选 适用于 Linux的Windows子系统 和 虚拟机平台 、 Hyper-v 。 重启电脑后再 Microsoft Store Windows应用商店 中下载合适的Ubuntu版本。 运行Ubuntu程序&#xff0c;如出现…

picoCTF-Web Exploitation-Most Cookies

Description Alright, enough of using my own encryption. Flask session cookies should be plenty secure! server.py http://mercury.picoctf.net:53700/ Hints How secure is a flask cookie? 我们先下载server.py&#xff0c;分析逻辑 from flask import Flask, render…

2024年,Web开发新趋势!

随着我们迈入新的一年&#xff0c;现在正是审视2024年网页开发领域开始流行哪些趋势的绝佳时机。回顾2023年的一系列更新&#xff0c;以下是来年一些热门话题的概览。 自主托管有回归的趋势 近些年&#xff0c;自主托管一直是网页开发者和公司托管其应用程序的默认方式。开发…