当前位置: 首页 > news >正文

Mockito测试框架中的方法详解

这里写目录标题

  • 第一章、模拟对象
    • 1.1)①mock()方法:
    • 1.2)②spy()方法:
  • 第二章、模拟对象行为
    • 2.1)模拟方法调用
        • ①when()方法
    • 2.2)模拟返回值
        • ②thenReturn(要返回的值)
        • ③doReturn()
    • 2.3)模拟并替换原方法的行为
        • ④thenAnswer()
        • ⑤doAnswer
    • 2.4)部分模拟时是否调用真实方法
        • ⑥thenCallRealMethod()
        • ⑦doCallRealMethod()
    • 2.5)模拟抛出异常
        • ⑧thenThrow()
        • ⑨doThrow()
    • 2.6)模拟构造函数和静态方法
        • ⑩模拟构造函数MockedConstruction
        • ⑩①模拟静态方法:MockedStatic
    • 2.7)其他方法
        • 使void方法什么也不做doNothing()
        • 重置模拟对象状态reset()方法:
  • 第三章、模拟对象行为验证
    • 3.1)验证调用次数
        • ①verify()方法:
        • ②verify(object, Mockito.times(2))方法
    • 3.2)验证是否发生交互
        • ③verifyNoMoreInteractions()方法:
        • ④verifyZeroInteractions()方法:
  • 第四章、Assert结果断言
    • 4.1)验证结果
        • ①验证是否相等:Equals
        • ②验证结果真假
        • ③验证结果是否为null
        • ④验证对象引用
        • ⑤验证是否满足指定条件
    • 4.2)使结果直接失败
        • ⑥使测试用例失败:fail()

第一章、模拟对象

1.1)①mock()方法:

用于创建给定类或接口的模拟对象,创建对象的另一种方式就是直接用@Mock/InjectMocks注解来创建模拟对象,第三章有介绍。

注意:无法mock final类和final方法,静态方法和静态对象,私有方法。

import java.util.List;
import static org.mockito.Mockito.*;public class MockitoMockMethodExample {public void testMultipleMocks() {// 使用 Mockito.mock() 方法创建多个模拟对象List<String> mockList1 = mock(List.class);List<String> mockList2 = mock(List.class);// 设置第一个模拟对象的预期行为when(mockList1.size()).thenReturn(5);// 设置第二个模拟对象的预期行为when(mockList2.size()).thenReturn(10);// 断言模拟对象的行为符合预期assert(mockList1.size() == 5);assert(mockList2.size() == 10);}
}

1.2)②spy()方法:

用于部分模拟对象,可以对真实对象的特定方法进行覆盖。它保留了真实对象的部分行为。Spy对象既可以模拟方法的返回值,也可以保留方法的实际行为。

示例中:spy() 方法创建了一个 ArrayList 对象的部分模拟,然后使用 when().thenReturn() 方法对 size() 方法进行了模拟。最后,调用部分模拟对象的真实方法时,模拟的方法返回了预期的值。

import static org.mockito.Mockito.*;// 示例:创建一个部分模拟的对象
List<String> list = new ArrayList<>();
List<String> listSpy = spy(list);// 示例:模拟部分方法
when(listSpy.size()).thenReturn(10);// 示例:调用部分模拟对象的真实方法
listSpy.add("one");
System.out.println(listSpy.size()); // 输出 10,因为 size() 方法被模拟为返回 10

第二章、模拟对象行为

2.1)模拟方法调用

①when()方法

用于指定模拟对象的方法调用,并设置相应的操作,例如返回值、异常等。
when():此方法需要一个方法调用作为参数(通常是模拟对象的一个方法)。它会记录下这个方法调用,并允许你接下来定义这个方法调用的行为。

when(service.方法名(参数))

2.2)模拟返回值

②thenReturn(要返回的值)

thenReturn(T value),这个方法需要你想要返回的值作为参数。当 when() 中指定的方法被调用时,模拟对象将返回这个值。

当使用模拟对象(用@Mock注释),选择thenReturn模拟有返回值(非void)的方法

如果使用监视对象(用@Spy注释),when(…) thenReturn(…)在返回指定值之前会进行实际方法调用。就需要处理这个方法可能抛出的异常。所以有异常的方法一般不使用thenReturn

when(service.方法名(参数)).thenReturn(要返回的值)

示例:

public class MockitoExample {@Testvoid testWhenThenReturn() {// 创建模拟对象List mockedList = Mockito.mock(List.class);// 定义当调用mockedList.get(0)时返回"first"Mockito.when(mockedList.get(0)).thenReturn("first");// 使用模拟对象System.out.println(mockedList.get(0));  // 输出 "first"System.out.println(mockedList.get(1));  // 输出 null,因为我们没有定义get(1)的行为}
}
③doReturn()

当使用模拟对象(用@Mock注释),选择thenReturn模拟无返回值(void)的方法

如果使用监视对象(用@Spy注释),doReturn(…) when(…)不会真正调用该方法。这意味着即使被调用的真实方法抛出异常,也不会影响测试。所以doReturn() 方法通常用于对部分模拟对象(spy)进行方法模。

doReturn(10).when(listSpy).size();

示例:

import static org.mockito.Mockito.*;// 示例:创建一个部分模拟的对象
List<String> list = new ArrayList<>();
List<String> listSpy = spy(list);// 示例:使用doReturn方法模拟部分方法
doReturn(10).when(listSpy).size();// 示例:调用部分模拟对象的真实方法
listSpy.add("one");
System.out.println(listSpy.size()); // 输出 10,因为 size() 方法被模拟为返回 10

2.3)模拟并替换原方法的行为

④thenAnswer()

如果在方法调用中需要固定的返回值,则应使用thenReturn()。 如果需要执行某些操作或替换原方法的行为,则应使用thenAnswer()

如下示例:在调用getCurrentTime方法时作用是获取当前的日期和时间。我想使用Instant.now().toEpochMilli();方法替换getCurrentTime方法的内部代码逻辑。

则需要先
1、实现接口org.mockito.stubbing.Answer的类的对象。
2、在方法answer(…)内部自定义行为。
3、我们从模拟对象中调用模拟方法getCurrentTime时,实际上是执行answer中的代码逻辑。

import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.time.Instant;public class TimeServiceTest {@Testpublic void testGetCurrentTime() {// 创建TimeService类的模拟对象TimeService timeService = Mockito.mock(TimeService.class);// 创建一个 Answer 对象,实现 answer 方法来返回当前系统时间Answer<Long> answer = new Answer<Long>() {public Long answer(InvocationOnMock invocation) throws Throwable {return Instant.now().toEpochMilli();}};// 使用 thenAnswer() 指定模拟对象的方法返回当前系统时间
Mockito.when(timeService.getCurrentTime()).thenAnswer(answer);// 调用模拟对象的方法,实际执行的是answer中的代码逻辑long currentTime = timeService.getCurrentTime();// 验证方法是否被调用Mockito.verify(timeService).getCurrentTime();// 进行进一步的断言}
}

我们可以也使用Java 8 lambda功能来实现answer方法。

public class TimeServiceTest {@Testpublic void testGetCurrentTime() {// 创建TimeService类的模拟对象TimeService timeService = Mockito.mock(TimeService.class);// 创建一个 Answer 对象,实现 answer 方法来返回当前系统时间Answer<Long> answer = new Answer<Long>() {public Long answer(InvocationOnMock invocation) throws Throwable {return Instant.now().toEpochMilli();}};// 使用 thenAnswer() 指定模拟对象的方法返回当前系统时间Mockito.when(timeService.getCurrentTime()).thenAnswer(answer);// 调用模拟对象的方法,实际执行的是answer中的代码逻辑long currentTime = timeService.getCurrentTime();// 验证方法是否被调用Mockito.verify(timeService).getCurrentTime();// 进行进一步的断言}
}
⑤doAnswer

更适用于对 void 方法进行模拟。你可以使用 doAnswer 来执行额外的操作,比如触发回调、记录日志等,因为 void 方法本身没有返回值。
创建一个 Answer 对象,实现 answer 方法来指定特定的操作或返回值,

示例中:通过Mockito的模拟,我们成功地替换了原来calculate方法的实际行为

doAnswer(answer).when(service).方法(Mockito.anyInt(), Mockito.anyInt());

示例:

// 假设有一个名为Service的类,其中包含一个方法
public class Service {public int calculate(int a, int b) {// 一些复杂的计算return a + b;}
}// 在测试中,使用Mockito来模拟Service类的行为
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;public class ServiceTest {@Testpublic void testCalculate() {// 创建Service类的模拟对象Service service = Mockito.mock(Service.class);// 创建一个 Answer 对象,实现 answer 方法来指定特定的操作或返回值Answer<Integer> answer = new Answer<Integer>() {public Integer answer(InvocationOnMock invocation) throws Throwable {int a = invocation.getArgument(0);int b = invocation.getArgument(1);// 在 answer 方法中执行特定的操作或返回特定的值return a * b;}};//doAnswer表示当calculate方法被调用时,执行特定的操作   
Mockito.doAnswer(answer).when(service).calculate(Mockito.anyInt(), Mockito.anyInt());// 调用模拟对象的方法//当调用service.calculate(2, 3)时,实际执行的是2 * 3,结果为6int result = service.calculate(2, 3);// 验证方法是否被调用,并且返回了预期的值Mockito.verify(service).calculate(2, 3);assertEquals(6, result);}
}

2.4)部分模拟时是否调用真实方法

⑥thenCallRealMethod()

用于部分模拟对象(spy)时,当调用指定方法时,实际调用对象的真实方法而不是模拟方法。特别是当需要部分模拟对象并且希望某些方法执行真实逻辑时。

when(service.方法名(参数)).thenCallRealMethod()

示例:

// 假设有一个名为UserService的类
public class UserService {public String process(String input) {// 实际的方法逻辑return "Processed: " + input;}
}// 创建UserService的部分模拟对象
UserService userService = Mockito.spy(UserService.class);// 当调用process方法时,执行实际的方法逻辑
Mockito.when(userService.process("input")).thenCallRealMethod();// 调用部分模拟对象的方法
String result = userService.process("input");// 输出结果,将会是"Processed: input",因为实际的方法逻辑被执行了
System.out.println(result);
⑦doCallRealMethod()

用于部分模拟对象(spy)时,用于调用真实对象的实际方法,而不是模拟方法的行为。这在部分模拟对象(spy)中特别有用,因为它允许部分模拟对象调用其真实的方法,而不是模拟方法的行为。

doCallRealMethod().when(someObject).someMethod();

示例:

// 创建一个部分模拟对象
SomeClass someObject = mock(SomeClass.class);
doCallRealMethod().when(someObject).someMethod();// 调用真实方法
someObject.someMethod();

2.5)模拟抛出异常

⑧thenThrow()

thenThrow 适用于有出参的方法,thenThrow方法指定了在调用该方法时抛出指定的异常,而 thenThrow() 方法更适合在特定条件下抛出异常。

when(mockedList.get(0)).thenThrow(new RuntimeException())

示例:这里是RuntimeException

when(service.方法名(参数)).thenThrow(new RuntimeException());

示例:

import static org.mockito.Mockito.*;public class ExampleTest {@Testpublic void testMethod() {// 创建被mock的对象SomeClass mockObj = mock(SomeClass.class);// 设置当调用mockObj.method时抛出异常when(mockObj.method(anyString())).thenThrow(new RuntimeException("Something went wrong"));// 调用被mock的方法这里会抛出异常mockObj.method("test");}
}
⑨doThrow()

doThrow 适用于 没有出参的方法,在测试中模拟抛出异常的情况。doThrow() 方法更适合在调用特定方法时强制抛出异常

doThrow(new RuntimeException()).when(mockedList).get(0)

示例:

import static org.mockito.Mockito.*;// 创建mock对象
List<String> mockedList = mock(List.class);// 指定当调用mockedList的get()方法时抛出异常
doThrow(new RuntimeException()).when(mockedList).get(0);// 调用被测方法
mockedList.get(0); // 这里会抛出指定的异常

2.6)模拟构造函数和静态方法

⑩模拟构造函数MockedConstruction

在单元测试中,当需要在测试中模拟某个类的实例时,使用MockedConstruction可以模拟构造函数的行为,如果没有模拟构造函数,那么在使用new关键字创建对象时,会执行实际的构造函数

作用:当需要在测试中模拟第三方库的对象时,可以使用MockedConstruction来模拟构造函数,而不实际调用第三方库的构造函数,从而避免对外部资源的依赖。

import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;public class ExampleTest {@Testvoid testWithMockedConstruction() {//模拟构造函数行为try (MockedConstruction<MyClass> mocked = Mockito.mockConstruction(MyClass.class)) {//模拟完以后再创建对象,此时执行的就是模拟的构造函数,而不是实际的MyClass myClass = new MyClass();//调用get方法Mockito.when(myClass.getName()).thenReturn("mocked value");// 在这里使用myClass进行测试}}
}
⑩①模拟静态方法:MockedStatic

MockedStatic是Mockito框架中的一个类,用于模拟静态方法的行为。通过使用MockedStatic,您可以模拟静态方法的返回值,以及验证静态方法的调用次数。

import org.mockito.MockedStatic;
import org.mockito.Mockito;public class Example {public void exampleMethod() {//YourClassWithStaticMethod是包含静态方法的类
try (MockedStatic<YourClassWithStaticMethod> mockedStatic = Mockito.mockStatic(YourClassWithStaticMethod.class)) {mockedStatic.when(YourClassWithStaticMethod::staticMethod("param1")).thenReturn("someValue");// 调用静态方法
YourClassWithStaticMethod.staticMethod("param1");// 验证静态方法是否被调用过
mockedStatic.verify(YourClassWithStaticMethod::staticMethod("param1"));}}
}

2.7)其他方法

使void方法什么也不做doNothing()

doNothing() 方法的作用是用于设置模拟对象的 void 方法不执行任何操作。因为 mock 对象中,void 函数就是什么都不做,所以该方法更适合 spy 对象。

Mockito.doNothing().when(service).方法名(参数)

示例1:

static class ExampleClass {public void hello() {System.out.println("吃过了");}}
/
public class MockDemo {@Testpublic void test() {ExampleClass exampleClass = spy(new ExampleClass ());ExampleClass .hello();  //打印吃过了// 通过doNothein让方法什么都不做doNothing().when(exampleClass ).hello();exampleClass.hello(); // 什么都不输出}
}

示例2:这是复制的国外一个博主的代码

List list = new LinkedList(); 
List spy = spy(list); 
//let's make clear() do nothing 
doNothing().when(spy).clear(); 
spy.add("one"); 
//clear() does nothing, so the list still contains "one" 
spy.clear();
重置模拟对象状态reset()方法:

用于重置模拟对象的状态或者将对象恢复到初始状态

import org.junit.Test;
import org.mockito.Mockito;// 创建一个模拟对象
List<String> mockedList = Mockito.mock(List.class);// 对模拟对象进行方法调用
mockedList.add("one");
System.out.println(mockedList.size()); // 输出 1// 重置模拟对象的状态
Mockito.reset(mockedList);// 再次对模拟对象进行方法调用
System.out.println(mockedList.size()); // 输出 0,因为模拟对象的状态已被重置

第三章、模拟对象行为验证

3.1)验证调用次数

①verify()方法:

用于验证模拟对象的指定方法是否被调用。可以进一步验证方法的调用次数和参数。

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;import java.util.List;public class MockitoExample {@Testvoid testMock() {// 创建模拟对象List mockedList = Mockito.mock(List.class);// 使用模拟对象mockedList.add("one");Mockito.verify(mockedList).add("one");// 验证模拟对象的某些行为是否发生过Mockito.verify(mockedList, Mockito.times(1)).add("one");}
}
②verify(object, Mockito.times(2))方法

是一个 Mockito 框架中的验证方法,用于验证某个行为在模拟对象上被调用了几次。times() 方法需要一个整数参数,代表你期望的调用次数。然后,将返回一个 VerificationMode 实例,这个实例可以和 verify() 方法一起使用,来检查某个操作是否被执行了指定次数。

下述代码;Mockito.times(2) 指的是,我们期望 add() 方法在模拟对象 mockedList 上被调用了两次。如果 add() 方法的实际调用次数不匹配我们的期望(例如,它只被调用了一次,或者三次),那么代码会抛出一个 MockitoAssertionError 异常。

public class MockitoExample {@Testvoid testTimes() {// 创建模拟对象List mockedList = Mockito.mock(List.class);// 模拟方法调用mockedList.add("one");mockedList.add("one");// 验证该方法是否被调用了两次Mockito.verify(mockedList, Mockito.times(2)).add("one");}
}

下述代码:不会抛出异常因为add了两次,与预期相符

import java.util.List;
import static org.mockito.Mockito.*;public class MockitoTimesExample {public void testMethodInvocation() {// 创建模拟对象List<String> mockList = mock(List.class);// 调用模拟对象的方法mockList.add("item1");mockList.add("item2");// 验证方法调用次数verify(mockList, times(2)).add(anyString());}
}

3.2)验证是否发生交互

③verifyNoMoreInteractions()方法:

verifyNoMoreInteractions() 方法用于验证mock对象在特定交互之后是否没有发生任何其他交互。它确保在测试中,mock对象在预期的交互之后没有进行多余交互。

多余交互指的是对于被mock的对象,测试代码中发生了未被预期的方法调用。这可能是因为测试代码中的某些逻辑导致了额外的方法调用。

import org.junit.Test;
import org.mockito.Mockito;public class ProcessorTest {@Testpublic void processTest() {// 创建 MyService 的 mock 对象MyService myMockService = Mockito.mock(MyService.class);// 创建 MyProcessor 对象,并传入 mock 对象MyProcessor myProcessor = new MyProcessor(myMockService);// 调用 MyProcessor 的 process() 和 process2() 方法myProcessor.process();myProcessor.process2();// 验证 mock 对象的交互Mockito.verify(myMockService).doSomething();Mockito.verify(myMockService).doSomething2();// 确保没有更多的交互发生Mockito.verifyNoMoreInteractions(myMockService);}
}
④verifyZeroInteractions()方法:

用于验证模拟对象上是否没有发生任何交互。它确保在测试中,mock对象没有与任何其他对象进行交互。关注的是整个测试过程中是否有任何交互。

import static org.mockito.Mockito.*;// 创建mock对象
List<String> mockedList = mock(List.class);// 调用被测方法
mockedList.clear();// 验证是否发生了交互
verify(mockedList).clear();
verifyNoMoreInteractions(mockedList); // 确保没有其他交互

第四章、Assert结果断言

4.1)验证结果

①验证是否相等:Equals

assertEquals(expected, actual):验证两个对象是否相等。
assertNotEquals(unexpected, actual):验证两个对象是否不相等。

示例:验证 Calculator.add(3, 5) 的结果是否等于 8。如果不相等,测试用例将会失败,并输出指定的失败信息。

import static org.junit.jupiter.api.Assertions.assertEquals;@Test
void testAddition() {int result = Calculator.add(3, 5);assertEquals(8, result, "The addition result should be 8");
}

assertArrayEquals(expectedArray, resultArray):验证两个数组是否相等。
assertArrayEquals(expecteds, actuals, delta):验证两个浮点数数组是否相等,可以指定误差范围。

示例:验证 expectedArray 和 resultArray 是否相等。如果两个数组不相等,测试用例将会失败,并输出指定的失败信息。

import static org.junit.jupiter.api.Assertions.assertArrayEquals;@Test
void testArrayEquality() {int[] expectedArray = {1, 2, 3};int[] resultArray = {1, 2, 3};assertArrayEquals(expectedArray, resultArray, "The arrays should be equal");
}
②验证结果真假

assertTrue(): 期待结果为true
assertFalse(): 期待结果为false

示例:验证 number 是否大于 0。如果条件不满足,测试用例将会失败,并输出指定的失败信息。

import static org.junit.jupiter.api.Assertions.assertTrue;@Test
void testIsPositive() {int number = 10;assertTrue(number > 0, "The number should be positive");
}
③验证结果是否为null

assertNull(object):期待结果为空。
assertNotNull(object): 期待结果为非空

示例:验证 obj 是否为空。如果对象不为空,测试用例将会失败,并输出指定的失败信息。

import static org.junit.jupiter.api.Assertions.assertNull;@Test
void testObjectNull() {Object obj = null;assertNull(obj, "对象应为空");
}
④验证对象引用

assertSame(object1, object2):验证两个对象引用是否指向同一个对象。
assertNotSame(object1, object2):验证两个对象引用是否不指向同一个对象。

示例:验证 obj1 和 obj2 是否引用同一个对象。如果两个对象引用不同的对象,测试用例将会失败,并输出指定的失败信息。

import static org.junit.jupiter.api.Assertions.assertSame;@Test
void testObjectReference() {Object obj1 = new Object();Object obj2 = obj1;assertSame(obj1, obj2, "两个对象应该引用同一个对象");
}
⑤验证是否满足指定条件

assertThat(actual, matcher):使用Matcher对象验证实际值是否满足指定条件。
assertThat 方法接受两个参数:实际值和Matcher对象。Matcher对象定义了对实际值的特定条件,例如包含特定子串、大于某个值等。通过使用Matcher对象,可以实现更加灵活和具体的断言验证。
示例1:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;// 示例:验证字符串是否包含指定子串
String actual = "Hello World";
Matcher<String> containsString = containsString("Hello");
assertThat(actual, containsString);

示例2:


// 示例:验证数字是否大于指定值
int actualNumber = 10;
Matcher<Integer> greaterThan = greaterThan(5);
assertThat(actualNumber, greaterThan);

4.2)使结果直接失败

⑥使测试用例失败:fail()

直接使测试用例失败,可用于标记测试用例未通过的情况。

import static org.junit.jupiter.api.Assertions.fail;@Test
void testSomething() {// 执行一些测试逻辑// 如果满足特定条件,则强制测试失败if (conditionIsMet) {fail("Test 测试 失败 because xxxx");}
}

相关文章:

Mockito测试框架中的方法详解

这里写目录标题 第一章、模拟对象1.1&#xff09;①mock()方法&#xff1a;1.2&#xff09;②spy()方法&#xff1a; 第二章、模拟对象行为2.1&#xff09;模拟方法调用①when()方法 2.2&#xff09;模拟返回值②thenReturn(要返回的值)③doReturn() 2.3&#xff09;模拟并替换…...

Atcoder ABC339 A - TLD

TLD 时间限制&#xff1a;2s 内存限制&#xff1a;1024MB 【原题地址】 所有图片源自Atcoder&#xff0c;题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 【输出格式】 【样例1】 【样例输入1】 atcoder.jp【样例输出1】 jp【样例说明…...

企业级DevOps实战

第1章 Zookeeper服务及MQ服务 Zookeeper&#xff08;动物管理员&#xff09;是一个开源的分布式协调服务&#xff0c;目前由Apache进行维护。 MQ概念 MQ&#xff08;消息队列&#xff09;是一种应用程序之间的通信方法&#xff0c;应用程序通过读写出入队列的消息&#xff0…...

C++中的new和delete

1.new和delete的语法 我们知道C语言的内存管理方式是malloc、calloc、realloc和free&#xff0c;而我们的C中除了可以使用这些方式之外还可以选择使用new和delete来进行内存管理。 new和delete的主要语法如下 从上面的代码我们只能知道new要比malloc好写一些&#xff0c;但是其…...

rtt设备io框架面向对象学习-dac设备

目录 1.dac设备基类2.dac设备基类的子类3.初始化/构造流程3.1设备驱动层3.2 设备驱动框架层3.3 设备io管理层 4.总结5.使用 1.dac设备基类 此层处于设备驱动框架层。也是抽象类。 在/ components / drivers / include / drivers 下的dac.h定义了如下dac设备基类 struct rt_da…...

腾讯云幻兽帕鲁服务器配置怎么选择合适?

腾讯云幻兽帕鲁服务器配置怎么选&#xff1f;根据玩家数量选择CPU内存配置&#xff0c;4到8人选择4核16G、10到20人玩家选择8核32G、2到4人选择4核8G、32人选择16核64G配置&#xff0c;腾讯云百科txybk.com来详细说下腾讯云幻兽帕鲁专用服务器CPU内存带宽配置选择方法&#xff…...

796. 子矩阵的和

Problem: 796. 子矩阵的和 文章目录 思路解题方法复杂度Code 思路 这是一个二维前缀和的问题。二维前缀和的主要思想是预处理出一个二维数组&#xff0c;使得每个位置(i, j)上的值表示原数组中从(0, 0)到(i, j)形成的子矩阵中所有元素的和。这样&#xff0c;对于任意的子矩阵(x…...

如何在 Python 中处理 Unicode

介绍 Unicode 是世界上大多数计算机的标准字符编码。它确保文本&#xff08;包括字母、符号、表情符号&#xff0c;甚至控制字符&#xff09;在不同设备、平台和数字文档中显示一致&#xff0c;无论使用的操作系统或软件是什么。它是互联网和计算机行业的重要组成部分&#xf…...

CSDN文章导出PDF整理状况一览

最近CSDN有了导出文章PDF功能&#xff0c;导出的PDF还可以查询&#xff0c; 因此&#xff0c;把文章导出PDF&#xff0c;备份一下自己的重要资料。 目前整理内容如下 No.文章标题整理时间整理之后 文章更新Size &#xff08;M&#xff09;10001_本地电脑-开发相关软件保持位…...

jmeter-05变量(用户定义变量,用户参数,csv文档参数化)

文章目录 一、jmeter有三种变量二、用户定义变量(这个更多的可以理解为全局变量)1、设置2、引用三、用户参数(可以理解为局部变量)1、设置2、引用3、用户参数化要配合线程组的线程数使用4、结果五、csv文档参数1、创建csv文件2、设置2、引用csv文件可以配合线程组的线程数,…...

CSS之水平垂直居中

如何实现一个div的水平垂直居中 <div class"content-wrapper"><div class"content">content</div></div>flex布局 .content-wrapper {width: 400px;height: 400px;background-color: lightskyblue;display: flex;justify-content:…...

2.8日学习打卡----初学RabbitMQ(三)

2.8日学习打卡 一.springboot整合RabbitMQ 之前我们使用原生JAVA操作RabbitMQ较为繁琐&#xff0c;接下来我们使用 SpringBoot整合RabbitMQ&#xff0c;简化代码编写 创建SpringBoot项目&#xff0c;引入RabbitMQ起步依赖 <!-- RabbitMQ起步依赖 --> <dependency&g…...

Unity学习笔记(零基础到就业)|Chapter02:C#基础

Unity学习笔记&#xff08;零基础到就业&#xff09;&#xff5c;Chapter02:C#基础 前言一、复杂数据&#xff08;变量&#xff09;类型part01&#xff1a;枚举数组1.特点2.枚举&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;申明枚举变量&#xff08;3&#xff…...

容器化的基础概念:不可变基础设施解释:将服务器视为乐高积木,而非橡皮泥。

不可变基础设施解释&#xff1a;将服务器视为乐高积木&#xff0c;而非橡皮泥。 想象一下用乐高积木代替橡皮泥进行搭建。使用橡皮泥时&#xff0c;您可以直接塑形和改变它。而使用乐高积木&#xff0c;您需要逐个零件搭建特定结构&#xff0c;并在需要时整体替换它们。这就是…...

智胜未来,新时代IT技术人风口攻略-第二版(弃稿)

文章目录 抛砖引玉 鸿蒙生态小科普焦虑之下 理想要落到实处校园鼎力 鸿蒙发展不可挡培训入场 机构急于吃红利企业布局 鸿蒙应用规划动智胜未来 技术人风口来临 鸿蒙已经成为行业的焦点&#xff0c;未来的发展潜力无限。作为一名程序员兼UP主&#xff0c;我非常荣幸地接受了邀请…...

Git分支和迭代流程

Git分支 feature分支&#xff1a;功能分支 dev分支&#xff1a;开发分支 test分支&#xff1a;测试分支 master分支&#xff1a;生产环境分支 hotfix分支&#xff1a;bug修复分支。从master拉取&#xff0c;修复并测试完成merge回master和dev。 某些团队可能还会有 reale…...

数据库管理-第150期 Oracle Vector DB AI-02(20240212)

数据库管理150期 2024-02-12 数据库管理-第150期 Oracle Vector DB & AI-02&#xff08;20240212&#xff09;1 LLM2 LLM面临的挑战3 RAG4 向量数据库LLM总结 数据库管理-第150期 Oracle Vector DB & AI-02&#xff08;20240212&#xff09; 作者&#xff1a;胖头鱼的鱼…...

MySQL双写机制

双写机制 问题的出现 在发生数据库宕机时&#xff0c;可能Innodb正在写入某个页到表中&#xff0c;但是这个页只写了一部分&#xff0c;这种情况被称为部分写失效&#xff0c;虽然innodb会先写重做日志,在修改页&#xff0c;但是重做日志中记录的是对页的物理操作&#xff0c;但…...

uniapp的配置和使用

①安装环境和编辑器 注册小程序账号 微信开发者工具下载 uniapp 官网 HbuilderX 下载 首先先下载Hbuilder和微信开发者工具 &#xff08;都是傻瓜式安装&#xff09;&#xff0c;然后注册小程序账号&#xff1a; 拿到appid&#xff1a; ②简单通过demo使用微信开发者工具和…...

【ES】--Elasticsearch的分词器深度研究

目录 一、问题描述及分析二、analyze分析器原理三、 multi-fields字段支持多场景搜索(如同时简繁体、拼音等)1、ts_match_analyzer配置分词2、ts_match_all_analyzer配置分词3、ts_match_1_analyzer配置分词4、ts_match_2_analyzer配置分词5、ts_match_3_analyzer配置分词6、ts…...

【Langchain Agent研究】SalesGPT项目介绍(三)

【Langchain Agent研究】SalesGPT项目介绍&#xff08;二&#xff09;-CSDN博客 上节课&#xff0c;我们介绍了salesGPT项目的初步的整体结构&#xff0c;poetry脚手架工具和里面的run.py。在run.py这个运行文件里&#xff0c;引用的最主要的类就是SalesGPT类&#xff0c;今天我…...

Java安全 URLDNS链分析

Java安全 URLDNS链分析 什么是URLDNS链URLDNS链分析调用链路HashMap类分析URL类分析 exp编写思路整理初步expexp改进最终exp 什么是URLDNS链 URLDNS链是Java安全中比较简单的一条利用链&#xff0c;无需使用任何第三方库&#xff0c;全依靠Java内置的一些类实现&#xff0c;但…...

【网站项目】026校园美食交流系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…...

使用raw.gitmirror.com替换raw.githubusercontent.com以解决brew upgrade python@3.12慢的问题

MacOS系统上&#xff0c;升级python3.12时&#xff0c;超级慢&#xff0c;而且最后还失败了。看了日志&#xff0c;发现是用curl从raw.githubusercontent.com上下载Python安装包超时了。 解决方案一&#xff1a;开启翻墙工具&#xff0c;穿越围墙 解决方案二&#xff1a;使用…...

深度学习的进展

#深度学习的进展# 深度学习的进展 深度学习是人工智能领域的一个重要分支&#xff0c;它利用神经网络模拟人类大脑的学习过程&#xff0c;通过大量数据训练模型&#xff0c;使其能够自动提取特征、识别模式、进行分类和预测等任务。近年来&#xff0c;深度学习在多个领域取得…...

[高性能] - 缓存架构

对于交易系统来说&#xff0c;低延时是核心业务的基本要求。因此需要对业务进行分级&#xff0c;还需要对数据按质量要求进行分类&#xff0c;主要包含两个维度&#xff1a;重要性&#xff0c;延时要求&#xff0c;数据质量。共包含以下三种场景&#xff1a; 1. 重要 延时性要…...

django实现外键

一&#xff1a;介绍 在Django中&#xff0c;外键是通过在模型字段中使用ForeignKey来实现的。ForeignKey字段用于表示一个模型与另一个模型之间的多对一关系。这通常用于关联主键字段&#xff0c;以便在一个模型中引用另一个模型的相关记录。 下面是一个简单的例子&#xff0…...

飞天使-k8s知识点14-kubernetes散装知识点3-Service与Ingress服务发现控制器

文章目录 Service与Ingress服务发现控制器存储、配置与角色 Service与Ingress服务发现控制器 在 Kubernetes 中&#xff0c;Service 和 Ingress 是两种不同的资源类型&#xff0c;它们都用于处理网络流量&#xff0c;但用途和工作方式有所不同。Service 是 Kubernetes 中的一个…...

任务调度

1.学习目标 1.1 定时任务概述 1.2 jdk实现任务调度 1.3 SpringTask实现任务调度 1.4 Spring-Task 分析 1.5 Cron表达式 https://cron.qqe2.com/ 2. Quartz 基本应用 2.1 Quartz 基本介绍 2.2 Quartz API介绍 2.3 入门案例 <dependency> <groupId>org.springframe…...

深刻反思现代化进程:20世纪与21世纪的比较分析及东西方思想家的贡献

深刻反思现代化进程&#xff1a;20世纪与21世纪的比较分析及东西方思想家的贡献 摘要&#xff1a;随着人类社会的快速发展&#xff0c;现代化已成为全球范围内的普遍追求。然而&#xff0c;20世纪至21世纪的现代化进程并非一帆风顺&#xff0c;它伴随着环境破坏、社会不平等和文…...

【FTP讲解】

FTP讲解 1. 介绍2. 工作原理3. 传输模式4. 安全5. 设置FTP服务器6. FTP命令 1. 介绍 FTP&#xff08;File Transfer Protocol&#xff09;是“文件传输协议”的英文缩写&#xff0c;它是用于在网络上进行数据传输的一种协议。FTP是因特网上使用最广泛的协议之一&#xff0c;它…...

java面试题整理

2023.2.14&#xff08;第二天&#xff09; 数组是不是对象&#xff1f; 在Java中&#xff0c;数组是对象。数组是一种引用类型&#xff0c;它可以存储固定大小的相同类型的元素序列。在Java中&#xff0c;数组是通过new关键字创建的&#xff0c;它们在内存中被分配为对象&…...

探索NLP中的N-grams:理解,应用与优化

简介 n-gram[1] 是文本文档中 n 个连续项目的集合&#xff0c;其中可能包括单词、数字、符号和标点符号。 N-gram 模型在许多与单词序列相关的文本分析应用中非常有用&#xff0c;例如情感分析、文本分类和文本生成。 N-gram 建模是用于将文本从非结构化格式转换为结构化格式的…...

JAVA-数组乱序

实现步骤 假设有一组数组numbers从数组中最后一个元素开始遍历设置一个随机数作为循环中遍历到的元素之前的所有元素的下标&#xff0c;即可从该元素之前的所有元素中随机取出一个每次将随机取出的元素与遍历到的元素交换&#xff0c;即可完成乱序 实例如下&#xff1a; im…...

Stable Diffusion 模型下载:majicMIX reverie 麦橘梦幻

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十...

Java开发四则运算-使用递归和解释器模式

使用递归和解释器模式 程序结构设计具体实现1. 先上最重要的实现类&#xff1a;ExpressionParser&#xff08;最重要&#xff09;2. 再上上下文测试代码&#xff1a;Context&#xff08;程序入口&#xff0c;稍重要&#xff09;3. 使用到的接口和数据结构&#xff08;不太重要的…...

[NSSCTF]-Web:[SWPUCTF 2021 新生赛]easyrce解析

先看网页 代码审计&#xff1a; error_reporting(0); &#xff1a;关闭报错&#xff0c;代码的错误将不会显示 highlight_file(__FILE__); &#xff1a;将当前文件的源代码显示出来 eval($_GET[url]); &#xff1a;将url的值作为php代码执行 解题&#xff1a; 题目既然允许…...

5.深入理解箭头函数 - JS

什么是箭头函数&#xff1f; 箭头函数是指通过箭头函数表达式创建的函数&#xff0c;是匿名函数。 箭头函数表达式的语法更简洁&#xff0c;但语义有差异&#xff0c;所以用法上也有一些限制。尽管如此&#xff0c;箭头函数依旧被广泛运用在需要执行“小函数”的场景。 箭头…...

高效的工作学习方法

1.康奈尔笔记法 在这里插入图片描述 2. 5W2H法 3. 鱼骨图分析法 4.麦肯锡7步分析法 5.使用TODOLIST 6.使用计划模板&#xff08;年月周&#xff09; 7. 高效的学习方法 成年人的学习特点&#xff1a; 快速了解一个领域方法 沉浸式学习方法&#xff1a; 沉浸学习的判据&am…...

【MySQL】-17 MySQL综合-3(MySQL创建数据库+MySQL查看数据库+MySQL修改数据库+MySQL删除数据库+MySQL选择数据库)

MySQL创建数据库查看数据库修改数据库删除数据库选择数据库 一 MySQL创建数据库实例1&#xff1a;最简单的创建 MySQL 数据库的语句实例2&#xff1a;创建 MySQL 数据库时指定字符集和校对规则 二 MySQL查看或显示数据库实例1&#xff1a;查看所有数据库实例2&#xff1a;创建并…...

【教学类-46-08】20240212立体鱼1.0

前期做了一个立体春字 作品展示 背景需求&#xff1a; 在南浔古镇的非遗文化馆里看到一个新年活动折纸——年年有鱼挂饰 我从网上搜索教程&#xff0c;完全可以用15*15的手工纸给孩子们做一套。 折纸教程 视频暂时不能查看https://haokan.baidu.com/v?pdwisenatural&vid1…...

【JVM篇】什么是jvm

文章目录 &#x1f354;什么是Java虚拟机&#x1f6f8;Java虚拟机有什么用&#x1f339;Java虚拟机的功能&#x1f388;Java虚拟机的组成 &#x1f354;什么是Java虚拟机 JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;可以运行 Java字节码文件…...

Vulnhub靶场 DC-9

目录 一、环境搭建 二、信息收集 1、主机发现 2、指纹识别 三、漏洞复现 1、dirsearch目录探测 2、sqlmap注入测试 3、文件包含漏洞 4、Knockd敲门服务 5、ssh爆破 ​​​​​​​6、提权 四、提取flag 一、环境搭建 Vulnhub靶机下载&#xff1a; 官网地址&#xff1a;https://…...

day2-理解 linux 云计算

1.解释服务器是什么&#xff1b; 服务器是一种高性能计算机&#xff0c;它的主要功能是提供计算服务和资源给其他计算机使用。在网络环境中&#xff0c;服务器扮演着重要的角色&#xff0c;它们可以存储和管理大量的数据&#xff0c;处理网络请求&#xff0c;提供应用程序运行…...

Android 13.0 开启禁用系统接收短信功能

1.概述 在13.0的系统rom定制化中,在一些wifi产品的机器中,对于系统4g部分的功能需要裁剪 比如拨打电话 接听电话 短信功能等这部分 需要禁用系统对应的功能,接下来就来初步分析下系统中接收短信部分功能,然后实现禁用接收短信功能 2.禁用和启用系统短信功能实现的核心类 …...

compile error ESP32cam.h no such file or directory

解决方法 可以参考这篇文章&#xff1a; But first, you will need to download the esp32cam.h library. For this go to Github and download the esp32cam Zip. GitHub - yoursunny/esp32cam: OV2640 camera on ESP32-CAM, Arduino library 具体就是下面的这篇重要的文章 …...

使用 Chainlit, Langchain 及 Elasticsearch 轻松实现对 PDF 文件的查询

在我之前的文章 “Elasticsearch&#xff1a;与多个 PDF 聊天 | LangChain Python 应用教程&#xff08;免费 LLMs 和嵌入&#xff09;” 里&#xff0c;我详述如何使用 Streamlit&#xff0c;Langchain, Elasticsearch 及 OpenAI 来针对 PDF 进行聊天。在今天的文章中&#xf…...

Gitee的使用教程(简单详细)

1.安装git&#xff08;我的电脑自带git&#xff0c;我没弄这步QAQ&#xff09; Git (git-scm.com)https://git-scm.com/ 安装好后在桌面点击鼠标右键会出现git GUI 和 git Bash&#xff08;没有的话点击显示更多选项&#xff09; 2.去gitee上注册一个账号 工作台 - Gitee.co…...

生成树(习题)

模板】最小生成树 生成树有两种方法&#xff0c;但是我只会克鲁斯卡尔算法&#xff0c;所以接下来下面的的题目都是按照这个算法来实现的&#xff0c;首先来见一下生么是这个算法&#xff0c;在之前的我写的一篇博客中有题使叫修复公路&#xff0c;其实这一题就是使用了这个算…...

ARMv8-AArch64 的异常处理模型详解之异常处理概述Handling exceptions

异常处理模型详解之异常处理概述 一&#xff0c;异常处理相关概念二&#xff0c;异常处理概述 一&#xff0c;异常处理相关概念 在介绍异常处理之前&#xff0c;有必要了解一些关于异常处理状态的术语&#xff1a; 当处理器响应一个异常时&#xff0c;我们称该异常被获取了&a…...