Mockito+PowerMock+Junit单元测试

news2025/3/2 2:10:54

一、单元测试用途

1、日常开发团队要求规范,需要对开发需求代码进行单元测试并要求行覆盖率达到要求,DevOps流水线也会开设相关门禁阀值阻断代码提交,一般新增代码行覆盖率80%左右。

二、Mock测试介绍

1、Mock是为了解决不同的单元之间由于耦合而难于开发、测试的问题。所以,Mock既能出现在单元测试中,也会出现在集成测试、系统测试过程中。Mock 最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。

2、Mock 测试就是在测试活动中,对于某些不容易构造或者不容易获取的比较复杂的数据/场景,用一个虚拟的对象(Mock对象)来创建用于测试的测试方法。

3、Mock重要作用

Mock是为了解决不同的单元之间由于耦合而难于开发、测试的问题。所以,Mock既能出现在单元测试中,也会出现在集成测试、系统测试过程中。

Mock 最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。

三、Mock测试所需依赖

 1、主要引入mockito-core/powermock-core

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>4.5.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>2.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.9</version>
            <scope>test</scope>
        </dependency>

 Mockito和PowerMock都是单元测试模拟框架,用于模拟被测试类的依赖项。Mockito基于动态代理的方式实现,而PowerMock在Mockito基础上增加了类加载器以及字节码篡改技术,使其可以实现对private/static/final方法的Mock 

四、Mock的核心功能

1、Mock对象创建

Mockito.mock(List.class); // Mock对象创建

public class VerifyMockExample {
    @Test
    public void testVerifyMock() {
        List<String> mockList = Mockito.mock(List.class);
        // 调用Mock对象的方法
        mockList.add("testCode");
        mockList.size();
        // 验证mockList.add("test")是否被调用过一次
        Mockito.verify(mockList,Mockito.times(1)).add("testCode");
        // 验证size()方法是否被调用过
        Mockito.verify(mockList,Mockito.times(1)).size();
        Assert.assertFalse(mockList.size()==1);
    }
}

verify系列方法 

Mockito.verify/Mockito.times()验证调用次数 

·verify(mock).methodCall():验证方法被调用

· verify(mock, times(n)).methodCall():验证方法被调用n次

· verify(mock, never()).methodCall():验证方法从未被调用

或者是通过注解来实现创建

    @Mock
    private UserInfoMapper mockUserInfoMapper;

    @InjectMocks
    private UserInfoServiceImpl userInfoServiceImplUnderTest;

    @Test
    public void testVerifyMock2(){
        List<String> mockList = Mockito.mock(List.class);
        mockList.add("Code1");
        mockList.add("Code2");
        // 验证是否调用两次
        Mockito.verify(mockList,Mockito.times(2));
    }
 // 验证这个方法从没有被调用过
 Mockito.verify(userMapper, Mockito.never()).getUserById(1);

 userMapper.getUserById(1);
 // 验证这个方法至少调用了1次
 Mockito.verify(userMapper, Mockito.atLeastOnce()).getUserById(1);

 userMapper.getUserById(1);
 // 验证当前方法调用了2次
 Mockito.verify(userMapper, Mockito.times(2)).getUserById(1);

 Mockito.when()使用when和thenReturn方法配置Mock对象的行为

Mockito.when( 对象.方法名 ).thenReturn( 自定义结果) //当调用了某个 Mock 对象的方法时,就回传我们想要的自定义结果。 

thenReturn系列方法 

//当使用任何整数值调用 userService 的 getUserById 方法时,就回传一个名字为 I'm mock 3 的 User 对象。
Mockito.when(userService.getUserById(Mockito.anyInt)).thenReturn( newUser( 3, "I'm mock"));
//限制只有当参数的数字是 3 时,才会回传名字为 I'm mock 3 的 user 对象。
Mockito.when(userService.getUserById( 3)).thenReturn( newUser( 3, "I'm mock"));
//当调用 userService 的 insertUser 方法时,不管传进来的 user 是什么,都回传 100。
Mockito.when(userService.insertUser(Mockito.any(User.class))).thenReturn( 100);

thenThrow系列方法 

//当调用 userService 的 getUserById 时的参数是 8 时,抛出一个 RuntimeException。
Mockito.when(userService.getUserById( 8)).thenThrow( new RuntimeException( "mock throw exception"));
//如果方法没有返回值的话(即方法定义为 public void myMethod {...}),要改用 doThrow 抛出 Exception。
Mockito.doThrow( new RuntimeException( "mock throw exception")).when(userService.print);

 

    @Test
    public void testVerifyMock3(){
        List<String> mockList = Mockito.mock(List.class);
        // 设置Mock对象的预期行为
        Mockito.when(mockList.get(0)).thenReturn("mockedValue");
        // 断言验证返回值
        Assert.assertEquals("mockedValue",mockList.get(0));
    }

实战案例:测试一个UserInfoServiceImpl层saveUser()方法.

原始方法:

    @Transactional
    @Override
    public void saveUser(UserInfo userInfo){
        userInfoMapper.saveUser(userInfo);
    }

单元测试:

    @Test
    public void testSaveUser() {
        // Setup
        final UserInfo userInfo = new UserInfo();
        userInfo.setId(0);
        userInfo.setUserName("userName");
        userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        // Run the test
        userInfoServiceImplUnderTest.saveUser(userInfo);
        // Verify the results
        Mockito.verify(mockUserInfoMapper).saveUser(new UserInfo());
    }

原始方法:

    @Override
    public List<UserInfo> queryListByUserName(String userName) {
        return userInfoMapper.queryListByUserName(userName);
    }

 单元测试方法:

    @Test
    public void testQueryListByUserName() {
        // Setup
        final UserInfo userInfo = new UserInfo();
        userInfo.setId(0);
        userInfo.setUserName("userName");
        userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> expectedResult = Arrays.asList(userInfo);

        // Configure UserInfoMapper.queryListByUserName(...).
        final UserInfo userInfo1 = new UserInfo();
        userInfo1.setId(0);
        userInfo1.setUserName("userName");
        userInfo1.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo1.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> userInfos = Arrays.asList(userInfo1);
        when(mockUserInfoMapper.queryListByUserName("userName")).thenReturn(userInfos);
        // Run the test
        final List<UserInfo> result = userInfoServiceImplUnderTest.queryListByUserName("userName");
        // Verify the results
        assertThat(result).isEqualTo(expectedResult);
    }

    @Test
    public void testQueryListByUserName_UserInfoMapperReturnsNoItems() {
        // Setup
        when(mockUserInfoMapper.queryListByUserName("userName")).thenReturn(Collections.emptyList());
        // Run the test
        final List<UserInfo> result = userInfoServiceImplUnderTest.queryListByUserName("userName");
        // Verify the results
        assertThat(result).isEqualTo(Collections.emptyList());
    }

 原始方法:

    @Override
    public List<UserInfo> queryUserInfoList(String createTime, List<Integer> idList) {
        return userInfoMapper.queryListByIds(createTime,idList);
    }

 单元测试方法:

    @Test
    public void testQueryUserInfoList() {
        // Setup
        final UserInfo userInfo = new UserInfo();
        userInfo.setId(0);
        userInfo.setUserName("userName");
        userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> expectedResult = Arrays.asList(userInfo);

        // Configure UserInfoMapper.queryListByIds(...).
        final UserInfo userInfo1 = new UserInfo();
        userInfo1.setId(0);
        userInfo1.setUserName("userName");
        userInfo1.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo1.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> userInfos = Arrays.asList(userInfo1);
        when(mockUserInfoMapper.queryListByIds("createTime", Arrays.asList(0))).thenReturn(userInfos);

        // Run the test
        final List<UserInfo> result = userInfoServiceImplUnderTest.queryUserInfoList("createTime", Arrays.asList(0));

        // Verify the results
        assertThat(result).isEqualTo(expectedResult);
    }

    @Test
    public void testQueryUserInfoList_UserInfoMapperReturnsNoItems() {
        // Setup
        when(mockUserInfoMapper.queryListByIds("createTime", Arrays.asList(0))).thenReturn(Collections.emptyList());

        // Run the test
        final List<UserInfo> result = userInfoServiceImplUnderTest.queryUserInfoList("createTime", Arrays.asList(0));

        // Verify the results
        assertThat(result).isEqualTo(Collections.emptyList());
    }

原始方法:Controller层,MockMvc

mockMvc.perform(request):执行一个HTTP请求,并返回ResultActions对象。
ResultActions.andExpect(expected):验证请求的处理结果,如状态码、响应体等。
ResultActions.andDo(handler):处理请求的响应,如将响应体写入文件等。
ResultActions.andReturn():返回已执行请求的结果,以便直接访问结果。
MockMvc.perform(request).andExpect(expected).andDo(handler).andReturn():链式调用,执行请求、验证结果并处理响应,返回结果。


@Slf4j
@RestController
public class UserInfoController {
    @Autowired
    private UserInfoService userInfoService;

    /**
     * 查询全部列表
     * @return
     */
    @RequestMapping("/boot/query/users")
    public List<UserInfo> getUserInfoList(){
        List<UserInfo> list = userInfoService.list();
        return list;
    }

    /**
     * 保存用户信息
     * @return
     */
    @RequestMapping("/boot/save/user")
    public String saveUser(){
        try {
            UserInfo user=new UserInfo();
            user.setUserName("MyBatis Log Free");
            userInfoService.save(user);
        } catch (Exception e) {
            log.error("save user error", e);
            throw new GlobalException("save user error");
        }
        return "success";
    }

    @RequestMapping("/boot/query/users/ids")
    public List<UserInfo> getUserInfoListIds(){
        List<Integer> list = Arrays.asList(1, 3, 5);
        String createTime="2022-09-05 15:11:21";
        List<UserInfo> userInfos = userInfoService.queryUserInfoList(createTime,list);
        return userInfos;
    }

    @RequestMapping("/boot/query/users/like")
    public List<UserInfo> getUserInfoListLike(){
        List<UserInfo> infoList = userInfoService.queryListByUserName("A");
        return infoList;
    }

    @RequestMapping("/boot/save/userinfo")
    public void saveUserInfo(){
        UserInfo userInfo = new UserInfo();
        userInfo.setId(5);
        userInfo.setUserName("Puck");
        Date startTime = new Date();
        Date endTime = new Date();
        userInfo.setCreateTime(startTime);
        userInfo.setUpdateTime(endTime);
        userInfoService.saveUser(userInfo);
    }
}

 单元测试方法如下:

@RunWith(SpringRunner.class)
@WebMvcTest(UserInfoController.class)
public class UserInfoControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserInfoService mockUserInfoService;

    @Test
    public void testGetUserInfoList() throws Exception {
        // Setup
        // Configure UserInfoService.list(...).
        final UserInfo userInfo = new UserInfo();
        userInfo.setId(0);
        userInfo.setUserName("MyBatis Log Free");
        userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> userInfos = Arrays.asList(userInfo);
        when(mockUserInfoService.list()).thenReturn(userInfos);

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
//        assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
    }

    @Test
    public void testGetUserInfoList_UserInfoServiceReturnsNoItems() throws Exception {
        // Setup
        when(mockUserInfoService.list()).thenReturn(Collections.emptyList());

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("[]");
    }

    @Test
    public void testSaveUser() throws Exception {
        // Setup
        when(mockUserInfoService.save(new UserInfo())).thenReturn(false);

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/save/user")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
        verify(mockUserInfoService).save(new UserInfo());
    }

    @Test
    public void testGetUserInfoListIds() throws Exception {
        // Setup
        // Configure UserInfoService.queryUserInfoList(...).
        final UserInfo userInfo = new UserInfo();
        userInfo.setId(0);
        userInfo.setUserName("MyBatis Log Free");
        userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> userInfos = Arrays.asList(userInfo);
        when(mockUserInfoService.queryUserInfoList("2022-09-05 15:11:21", Arrays.asList(0))).thenReturn(userInfos);

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/ids")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
    }

    @Test
    public void testGetUserInfoListIds_UserInfoServiceReturnsNoItems() throws Exception {
        // Setup
        when(mockUserInfoService.queryUserInfoList("2022-09-05 15:11:21", Arrays.asList(0)))
                .thenReturn(Collections.emptyList());

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/ids")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("[]");
    }

    @Test
    public void testGetUserInfoListLike() throws Exception {
        // Setup
        // Configure UserInfoService.queryListByUserName(...).
        final UserInfo userInfo = new UserInfo();
        userInfo.setId(0);
        userInfo.setUserName("MyBatis Log Free");
        userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
        final List<UserInfo> userInfos = Arrays.asList(userInfo);
        when(mockUserInfoService.queryListByUserName("A")).thenReturn(userInfos);

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/like")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
    }

    @Test
    public void testGetUserInfoListLike_UserInfoServiceReturnsNoItems() throws Exception {
        // Setup
        when(mockUserInfoService.queryListByUserName("A")).thenReturn(Collections.emptyList());

        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/like")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("[]");
    }

    @Test
    public void testSaveUserInfo() throws Exception {
        // Setup
        // Run the test
        final MockHttpServletResponse response = mockMvc.perform(get("/boot/save/userinfo")
                        .accept(MediaType.APPLICATION_JSON))
                .andReturn().getResponse();

        // Verify the results
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
        assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
        verify(mockUserInfoService).saveUser(new UserInfo());
    }
}

 @Mock用于模拟不属于 Spring 上下文的对象,而@MockBean用于模拟属于 Spring Boot 应用程序中的 Spring 上下文的对象。@MockBean提供与 Spring Boot 测试框架的无缝集成,并允许在测试期间用模拟对象轻松替换实际 bean 

Mockito提供了多种参数匹配器(Matchers)用于更灵活的验证和配置行为:

import static org.mockito.ArgumentMatchers.*;
when(mockRepository.findById(anyInt())).thenReturn(Optional.of(user));
verify(mockRepository).findById(eq(1));

常见的匹配器包括:

  ·any():匹配任何参数

  · anyInt():匹配任何整数参数

  · eq(value):匹配特定值

  · isNull():匹配null值

  · notNull():匹配非null值

Mock异常

Mockito.when(userMapper.getUserById(Mockito.anyInt())).thenThrow(new RuntimeException("运行时错误"));

Assertions.assertThrowsExactly(RuntimeException.class, () -> userMapper.getUserById(1));

// 对于没有返回值的方法,不能使用thenThrow()来抛出异常,可以使用doThrow()来抛出异常。
Mockito.doThrow(new RuntimeException("运行时错误")).when(userMapper).getUserById(1);
Assertions.assertThrowsExactly(RuntimeException.class, () -> userMapper.getUserById(1));

@MockBean 是 Spring Boot 提供的注解,它用于在测试中创建一个 mock 对象,并将其注入到 Spring 上下文中,替换掉原来的真实 Bean。 需要使用SpringJUnit4ClassRunner.class之类的注解

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

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

原始代码:

@Service
public class TemplateUserServiceImpl implements TemplateUserService {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Transactional
    @Override
    public void saveUser() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(7);
        userInfo.setUserName("Boot");
        Date startTime = new Date();
        Date endTime = new Date();
        userInfo.setCreateTime(startTime);
        userInfo.setUpdateTime(endTime);
        // JdbcTemplate的写入datetime,使用in方式
//        String sql="insert into user_info(user_name,create_time,update_time) values(:user_name,:create_time,:update_time)";
        String sql="insert into user_info(user_name,create_time,update_time) values(:userName,:createTime,:updateTime)";
        SqlParameterSource sqlParameterSource=new BeanPropertySqlParameterSource(userInfo);
//        HashMap paramMap = new HashMap<>();
//        paramMap.put("user_name",userInfo.getUserName());
//        paramMap.put("create_time",userInfo.getCreateTime());
//        paramMap.put("update_time",userInfo.getUpdateTime());
//        jdbcTemplate.update(sql,paramMap);
        jdbcTemplate.update(sql,sqlParameterSource);
    }
}

 对应单元测试代码:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class TemplateUserServiceImplTest {

    @Mock
    private NamedParameterJdbcTemplate mockJdbcTemplate;

    @InjectMocks
    private TemplateUserServiceImpl templateUserServiceImplUnderTest;

    @Test
    public void testSaveUser() {
        // Setup
        // Run the test
        templateUserServiceImplUnderTest.saveUser();

        // Verify the results
        verify(mockJdbcTemplate).update(
                eq("insert into user_info(user_name,create_time,update_time) values(:userName,:createTime,:updateTime)"),
                any(SqlParameterSource.class));
    }

    @Test
    public void testSaveUser_NamedParameterJdbcTemplateThrowsDataAccessException() {
        // Setup
        when(mockJdbcTemplate.update(
                eq("insert into user_info(user_name,create_time,update_time) values(:userName,:createTime,:updateTime)"),
                any(SqlParameterSource.class))).thenThrow(DataAccessException.class);

        // Run the test
        assertThatThrownBy(() -> templateUserServiceImplUnderTest.saveUser()).isInstanceOf(DataAccessException.class);
    }
}

@MockBean 和 @SpyBean和@Spy以及@Mock的使用场景和区别 

 

五、单元测试生成插件

1、IDEA中安装Squaretest插件使用

文件右键即可生成对应单元测试,需要修改测试用例,满足业务诉求。

 

2、破解插件过程 

idea版本:

下载字节码编译工具:jclasslib。

jclasslib下载地址 

JAR包路径:C:\Users\Administrator\AppData\Roaming\JetBrains\IntelliJIdea2023.3\plugins\Squaretest 

 说明:不用版本的Squaretest插件的jar包名称或许不一样,找空间最大的那个,约15M左右的那个。

最后一步点击保存按钮,选择“overwrite”时,此时一定要将idea关闭,否则会保存失败的. 

最后破解成功,可以正常使用。

 

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

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

相关文章

2024CVPR《HomoFormer》

这篇论文提出了一种名为HomoFormer的新型Transformer模型,用于图像阴影去除。论文的主要贡献和创新点如下: 1. 研究背景与动机 阴影去除的挑战:阴影在自然场景图像中普遍存在,影响图像质量并限制后续计算机视觉任务的性能。阴影的空间分布不均匀且模式多样,导致传统的卷积…

JavaEE之CAS

上文我们认识了许许多多的锁&#xff0c;此篇我们的CAS就是从上文的锁策略开展的新概念&#xff0c;我们来一探究竟吧 1. 什么是CAS&#xff1f; CAS: 全称Compare and swap&#xff0c;字⾯意思:“比较并交换”&#xff0c;⼀个CAS涉及到以下操作&#xff1a; 我们假设内存中…

国产编辑器EverEdit - 复制为RTF

1 复制为RTF 1.1 应用背景 在写产品手册或者其他文档时&#xff0c;可能会用到要将产品代码以样例的形式放到文档中&#xff0c;一般的文本编辑器拷贝粘贴到Word中也就是普通文本&#xff0c;没有语法着色&#xff0c;这样感观上不是太好&#xff0c;为了让读者的感观更好一点…

LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145185794 Scaling Laws (缩放法则) 是大模型领域中&#xff0c;用于描述 模型性能(Loss) 与 模型规模N、数据量D、计算资源C 之间关系的经验规律…

CSS认识与实践

目录 CSS 是什么 基本语法规范 引入方式 内部样式表 行内样式表 外部样式 空格规范 选择器 选择器的功能 选择器的种类 基础选择器 标签选择器 类选择器 id 选择器 通配符选择器 基础选择器小结 复合选择器 后代选择器 子选择器 并集选择器 伪类选择器 复合…

vue项目引入阿里云svg资源图标

1&#xff1a;生成svg图标 登录阿里云官网 1.1 创建项目组 1.2 从阿里云网站上面获取喜欢的图标加入到已有的项目组 1.3 如果团队有自己的设计师&#xff0c;也可以让设计师上传自己的svg图标到阿里云指定的项目组&#xff1b; 使用的时候&#xff0c;把 资源包下载到本地项…

Redis 中 TTL 的基本知识与禁用缓存键的实现策略(Java)

目录 前言1. 基本知识2. Java代码 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 单纯学习Redis可以看我前言的Java基本知识路线&#xff01;&#xff01; 对于Java的基本知识推荐阅读&#xff1a; java框架…

使用nginx搭建通用的图片代理服务器,支持http/https/重定向式图片地址

从http切换至https 许多不同ip的图片地址需要统一进行代理 部分图片地址是重定向地址 nginx配置 主站地址&#xff1a;https://192.168.123.100/ 主站nginx配置 server {listen 443 ssl;server_name localhost;#ssl证书ssl_certificate ../ssl/ca.crt; #私钥文件ssl_ce…

Unix 与 Linux 深度应用与对比分析

文章目录 引言Unix 与 Linux 的相似之处1. 设计理念2. 文件系统结构3. 命令行界面4. 多用户多任务支持 Unix 与 Linux 的不同之处1. 开源性2. 内核架构3. 应用场景4. 发行版 Unix 和 Linux 的开发语言1. C 语言2. 脚本语言 在 Unix 和 Linux 上开发简单应用示例1. 编写一个简单…

事务机制及Spring事务管理

事务概览 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位。 事务会将所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;换句话说&#xff1a;这些操作要么同时成功、要么同时失败。 具体案例 我们先看一个需求&#xff1a;现在有两张数据库表&…

48.【6】BUUCTF WEB BabySQL

进入靶场 order by 判断字节数 输入内容是 1 order by 2# 显示图片内容&#xff0c;知被过滤了 一般最简单的绕过方法是双写或大小写 尝试双写 It is ok continue 经过多次尝试&#xff0c;4时异常&#xff0c;所以字节数是3 union select都被过滤了 双写解决&#xff0c;成…

Spring6.0新特性-HTTP接口:使用@HttpExchange实现更优雅的Http客户端

文章目录 一、概述二、使用1、创建接口HttpExchange方法2、创建一个在调用方法时执行请求的代理3、方法参数4、返回值5、错误处理&#xff08;1&#xff09;为RestClient&#xff08;2&#xff09;为WebClient&#xff08;3&#xff09;为RestTemplate 注意 一、概述 官方文档…

高效并发编程:掌握Go语言sync包的使用方法

高效并发编程&#xff1a;掌握Go语言sync包的使用方法 引言基本概念并发与并行互斥锁&#xff08;Mutex&#xff09;读写锁&#xff08;RWMutex&#xff09;等待组&#xff08;WaitGroup&#xff09;一次性操作&#xff08;Once&#xff09;条件变量&#xff08;Cond&#xff0…

.Net Core webapi 实现JWT认证

文章目录 需求准备创建JWT配置创建JWTService注册JWT创建中间件读取jwt的token在需要的接口上添加属性启动认证启动swagger的授权认证使用 需求 实现一个记录某个用户所有操作的功能 准备 创建你的webapi项目从nuget下载安装JWT资源包根据你的项目使用.net版本下载对应的jwt…

Linux《Linux简介与环境的搭建》

在学习了C或者是C语言的基础知识之后就可以开始Linux的学习了&#xff0c;现在Linux无论是在服务器领域还是在桌面领域都被广泛的使用&#xff0c;所以Linxu也是我们学习编程的重要环节&#xff0c;在此接下来我们将会花大量的时间在Linxu的学习上。在学习Linux初期你可以会像初…

从零开始:Gitee 仓库创建与 Git 配置指南

引言 Git 是一款广泛使用的版本控制工具&#xff0c;它能够帮助开发者在开发过程中高效地管理代码的版本。而 Gitee&#xff08;码云&#xff09;是国内知名的 Git 托管平台&#xff0c;它提供了强大的代码托管、团队协作和项目管理功能。如果你是 Git 和 Gitee 的新手&#x…

创建模式、结构模式及行为模式

谁在什么地方提供什么功能&#xff1f; 要设计几个类?这些类各个是什么功能&#xff1f;相互间的关系是什么&#xff1f; 创建模式指的是对象那么多&#xff0c;怎么把它"生"出来&#xff1f;生几个&#xff1f;从这个角度上来说数组就是一种另类的创建模式。主要…

SpringBoot链接Kafka

一、SpringBoot生产者 &#xff08;1&#xff09;修改SpringBoot核心配置文件application.propeties, 添加生产者相关信息 # 连接 Kafka 集群 spring.kafka.bootstrap-servers192.168.134.47:9093# SASL_PLAINTEXT 和 SCRAM-SHA-512 认证配置 spring.kafka.properties.securi…

Linux下源码编译安装Nginx1.24及服务脚本实战

1、下载Nginx [rootlocalhost ~]# wget -c https://nginx.org/download/nginx-1.24.0.tar.gz2、解压 [rootlocalhost ~]# tar xf nginx-1.24.0.tar.gz -C /usr/local/src/3、安装依赖 [rootlocalhost ~]# yum install gcc gcc-c make pcre-devel openssl-devel -y4、 准备 N…

解答二重积分

什么是积分&#xff1f; 一元函数的积分。具体计算过程&#xff0c;是将无数个小矩形加起来&#xff0c;然后求极限。 而今天我们要讲的积分&#xff0c;是二元函数的积分。我们可以用曲顶柱体的体积来理解。 什么是曲顶柱体&#xff1f; 它的底是xoy平面上的一个闭区域。顶是…