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

JUnit

Junit

简介

JUnit是一个开源的java单元测试框架,它是XUnit测试体系架架构的一种体现

  • 是Java语言事实上的标准单元测试库
  • 真正的优势来自于JUnit所采作用的思想和技术,而不是框架本身。推动了单元测试、测试先行的编程和测试驱动的开发
  • JUnit衍生了许多xUnit工具,将单元测试的优势应用与各种语言。影响了各种平台和语言上的程序员的测试工作
  • 专门针对Java语言设计,使用广泛。
  • JUnit是事实上的标准单元测试框架

优点

  • 可以使用断言(Assertion)测试期望结果;
  • 可以方便地组织和运行测试
  • 可以方便地查看测试结果
  • 常用IDE(例如IntelliJIdea、eclipse)都集成了JUnit
  • 可以翻遍地集成到Maven

JUnit的设计

  • TestCases:一个测试
  • TestSuite:包含一组TestCases,表示一组测试
  • TestFixture:测试环境
  • TestResult:用于收集测试结果
  • TestRunner:用于运行测试
  • TestListener:用于监听测试过程,收集测试数据
  • Assert:用于断言测试结果是否正确

Assert

使用Assert断言:

  • 断言相等:assertEquals(100,x)
  • 断言数组相等:assertArrayEquals({1,2,3},x)
  • 浮点数断言相等:assertEquals(3.14,x,0.5)
  • 断言为null:assertNull(x)
  • 断言为true/false:assertTrue(x>0)/assertFalse(x<0)
  • 其它:assertNotEquals/assertNotNull

总结

  • 一个TestCase包含一组相关的测试方法
  • 使用Assert断言测试结果(注意浮点数assertEquals要指定delta)
  • 每个测试方法必须完全独立
  • 测试代码必须非常简单
  • 不能为测试代码再编写测试
  • 测试需要覆盖各种输入条件,特别是边界条件

Assert

public static void assertEquals(double expected,double actual,double delta){//expecdted		预期值//actual		实际值//delta			误差值
}
//待测程序
public class Calculator{public double add(double number1,double number2){//返回两数之和return number1+number2;}
}

1.单元测试代码

import junit.framework.TestCase;//引入相应包
public class TestCalculator extends TestCase{public void testAdd(){Calculator calcuator = new Calculator();double result = calculator.add(10,15);Assert.assertEquals(60,result,0);}
}
assertTrue
assertFalse
assertEquals支持boolean,long,int,String等等
assertNotNull
assertNull
assertSame只支持Object类型(对象直接比较)
assertNotSame
fail

hamcrest

Hamcrest框架提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活。

Hamcrest是一个书写匹配器对象时允许直接定义匹配规则的框架。

JUnit4.4引入了使用全新的断言语法:assertThat,结合Hamcest提供的匹配符,只用这一个方法,就可以实现所有的测试;

//assertThat语法如下
assertThat(T actulal,Matcher<T> matcher);
assertThat(String reson,T actual,Matcher<T> matcher);
//reson		失败提示信息
//actual	实际值
//matcher	匹配器

注意事项

  1. 必须导入JUnit4.4之后的版本才能使用assertThat方法

  2. 不需要继承TestCase类,但是需要测试方法前加@Test

  3. 需要导入Hamcrest类库:hamcrest-core-1.3.0.jar和hamcrest-library-1.3.0.jar

  4. 在eclipse或MyEclipse中使用时,建议使用自定义的Library。

    否则抛出异常:java.lang.SecurityExcepiton

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import org.junit.Test;
public class CalculatorTest2{Calculator calc = new Calculator();@Testpublic void testAdd(){int result = calc.add(10,20);assertThat(result,is(30));}
}

Mathcers的一般匹配器

//所有条件必须都成立测试才能通过,相当于"与"(&&)
assertThat(n,allOf(greaterThan(1),lessThan(15));
//所有条件只要有一个成立测试通过,相当于”或"(||)
assertThat(n,anyOf(greaterThan(16),lessThan(8)));
//无论什么条件,永远为true
assertThat(n,anyThing());
//待测的object等于后面给出的object,则测试通过
assertThat(obj,is(obj));
//与is匹配符正好相反
assertThat(obj,not(obj));

Mathcers的字符串匹配器

//str包含子字符串“software”则测试通过
assertThat(str,containsString("software"));
//str以子字符串“software”结尾则测试通过
assertThat(str,endsWith("software"));
//str以子字符串“software”开始则测试通过
assertThat(str,startsWith("software"));
//相等则测试通过,可测数值,字符串和对象之间是否相等,相当于Object的equals方法
assertThat(n,equalTo(nExpected));
//字符串str在忽略大小写的情况下等于"software"则测试通过
assertThat(str,equalToIgnoringCase("software"));
//忽略头尾的的任意个空格的情况下是否相等。注意:字符串中的空格不能被忽略
assertThat(str,equalToIgnoringWhiteSpace("software"));

Matchers的数值型匹配器

//浮点型数d在20.0+_0.5范围之内则测试通过
assertThat(d,closeTo(20.0,0.5));
//数值d大于16.0则测试通过
assertThat(d,greaterThan(16.0));
//数值d小于16.0则测试通过
assertThat(d,lessThan(16.0));
//数值d大于等于16.0则测试通过
assertThat(d,greaterThanOrEqualTo(16.0));
//数值d小于等于16.0则测试通过
assertThat(d,lessThanOrEqualTo(16.0));

Matchers的集合匹配器

//Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项测试通过
assertThat(mapObject,hasEntry("key","value"));
//Map对象mapObject含有键值"key"则测试通过
assertThat(mapObject,hasKey("key"));
//Map对象mapObject含有元素值"value"则测试通过
assertThat(mapObject,hasValue("value"));
//迭代对象iterableObject含有元素"element"项则测试通过
assertThat(iterableObject,hasItem("element"));

@Test

对可能抛出的异常进行测试:

  • 异常本身是方法签名的一部分:

    public static int parseInt(String s) throws NumberFormatException

  • 测试错误的输入是否导致特定的异常:

    Integer.parseInt(null)

    Integer.parseInt(“”)

    Integer.parseInt(“xyz”)

在测试类中,并不是每一个方法都时用于测试的,你必须使用@Test注解来表命那些事测试方法

  • 测试方法地声明要求

    • 返回必须为void
    • 不能有任何形参
  • @Test(timeout=1000)

    • 测试逻辑复杂地循环,防止死循环,单位为毫秒

      @Test(timeout=1000)
      public void testSquareRoot(){calc.squareRoot(4);assertTaht(calc.getResult(),is(2));
      }
      
  • @Test(expected=ArithmeticException.class)

    检测是否跑出来我们指定地异常,它若没抛出,则为bug

    @Test(expected=ArithmeticException.class)
    public void testDivide(){calc.divide(0);
    }
    

@Ignore

  • 被忽略地测试方法

    • 某些方法尚未完成或方法已经过时,不参与此次测试

    • 在某些条件下才能测试该方法(如:需要一个数据库连接,而在本地测试的时候,数据库并没有连接

    • 测试结果会提示有几个测试被忽略,而不是失败

      @Ignore("方法还未实现")
      @Test
      public void testMultiply(){calc.multiply(2);
      }
      

Fixture

某些阶段必然被调用的代码

@Test

@Ignore

@Before

@After

@BeforeClass

@AfterClass

@RunWith

@Parameters

@Suite.SuiteClasses

@Before和@After

  • 注解@Before
    • 在每个测试方法执行之前都要执行一次
    • 在每个测试执行之前需要进行的准备工作
  • 注解@After
    • 在每个测试方法执行之后要执行一次
    • 在任何测试执行之后进行的收尾工作
  • @Before和@After标示的方法只能各有一个

JUnit使用@Before和@After

  • 在@Before方法中初始化测试资源
  • 在@After方法中释放测试资源、
public class CalculatorTest{Calculator calc;@Beforepublic void setUp(){calc = new Calculator();}@Afterpublic void tearDown(){calc = null;}
}

JUnit对于每个@Test方法:

  1. 实例化CalculatorTest
  2. 执行@Before方法
  3. 执行@Test方法
  4. 执行@After方法

使用@Before和@After可以保证:

  • 单个@Test方法执行前会创建新的XxxTest实例,实例变量的状态不会传递给下一个@Test方法
  • 单个@Test方法执行前后会执行@Before和@After方法

@BeforeClass和@AfterClass静态方法:

  1. 在执行所有@Test方法前执行@BeforeClass静态方法
  2. 执行所有测试
  3. 在执行所有@Test方法后执行@AfterClass静态方法

@BeforeClass和@AfterClass静态方法

public class CalculatorTest{static StringBuilder builder;@BeforeClasspublic static void beforeClass(){builder = new StringBuilder();}
}
  • @BeforeClass静态方法初始化的对象只能存放在静态字段中
  • 静态字段的状态会影响到所有@Test

@BeforeClass和@AfterClass

  • 注解@BeforeClass

    所有测试开始之前运行

  • 注解@AfterClass

    所有测试结束之后运行

  • @BeforeClass和@AfterClass标示的方法只能各有一个

  • 该方法必须是public static修饰

JUnit的执行逻辑

invokeBeforeClass(CalculatorTest.class);//@BeforeClass
for(Method testMethod : findTestMethods(CalculatorTest.class)){CalculatorTest test = new CalculatorTest();//newtest.setUp();//@BeforetestMethod.invoke(test);//@Testtest.tearDown();//@After
}
invokeAfterClass(CalculatorTest.class);//@AfterClass

总结

初始化资源称为Fixture

  • @Before:初始化测试对象,例如:input = new FileInputStream();
  • @After:销毁对象@Before创建的测试对象,例如:input。close()
  • @BeforeClass:初始化非常耗时的资源,例如:创建数据库
  • @AfterClass:清理@BeforeClass创建的资源,例如:删除数据库
public class SequenceTest {@BeforeClasspublic static void setUpBeforeClass() throws Exception{System.out.println("setUpBeforeClass");}@AfterClasspublic static void treaDownAfterClass() throws Exception{System.out.println("tearDownAfterClass");}public SequenceTest(){System.out.println("	new SequenceTest");}@Beforepublic void setUp() throws Exception{System.out.println("		setUp");}@Afterpublic void treaDown() throws Exception{System.out.println("		treaDown");}@Testpublic void test1001() {System.out.println("		test1001");}@Testpublic void test1002() {System.out.println("		test1002");}@Testpublic void test1003() {System.out.println("		tset1003");}
}
#执行结果
setUpBeforeClassnew SequenceTestsetUptest1001treaDownnew SequenceTestsetUptest1002treaDownnew SequenceTestsetUptset1003treaDown
tearDownAfterClass
  • 理解JUnit执行测试的生命周期
  • @Before用于初始化测试对象,测试对象以实例变量存放
  • @After用于清理@Before创建的对象
  • @BeforeClass用于初始化耗时资源,以静态变量存放
  • @AfterClass用于清理@BeforeClass创建的资源

@RunWith

@Runwith放在测试类名之前,用来确定这个类怎么运行的。不标注时会使用默认运行器。

常见的JUnit运行器

当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用这个注解所指明的运行器(runner)来运行测试,而不是JUnit默认的运行器

  1. 默认运行器

    @RunWith(Junit4.class)

  2. 参数化运行器

    • @RunWith(Patammeterized.class)配合@Patameters使用junit的参数化功能
    • @RunWith(Suite.class)
    • @SuiteClass({ATest.class,BTest.class,CTest.class})
    • 配合使用测试集功能
  3. 兼容junit3.8的运行器

    @RunWith(JUnit38ClassRunner.class)

  4. 其他运行器

    例如@RunWith(SpringJUnit4ClassRunner.class)集成了spring的一些功能

//测试类必须标记为@RunWith(Patameterized.class)
@RunWith(Parameterized.class)
public class AbsTest(){private int input;private int expected;//参数必须由静态方法data()返回//返回类型为Collection<Object[]>//静态方法必须标记为@Patameters@Parameterspublic static Collection<?> data(){return arrays.asList(new Object[][]{{0,0},{1,1},{-1,1}})}//构造方法参数必须和测试参数对应public AbsTest(int input,int expected){this.input = input;this.expected = expected;}//测试Math@Testpublci void testAbs(){int result=Math.abs(this.input);Assert.asserEquals(this.expected,result)}
}
@RunWith(Patameterized.class)
public class SqureTest{private static Calclator calculator = new Calculator();private int param;private int result;@Parameterspublic static Collection data(){return Arrays.asList(new Object[][]{{2,4},{0,0},{-3,9}});}//构造方法,对变量进行初始化public SquareTest(int param,int result){this.param = param;this.result = result;}@Testpublic void squareTest(){calculator.square(param);assertEquals(result,calclulator.getResult());}
}

实现步骤

  1. 为类指定运行器:@RunWith(Parameterized.class)
  2. 创建提供数据的方法,加上@Parameters注解,方法必须是static的,并且返回一个集合Collection;
  3. 在测试类的构造方法中为各个参数赋值
  4. 编写测试方法,它会根据参数的组数来运行测试多次
  • 注意
    1. 要为这种测试专门生成一个新的类
    2. 要为这个类指定一个Runner,而不能使用默认的Runner

JUnit为我们提供了打包测试的功能,将所有需要运行的测试类集中起来,一次性的运行完毕

@RunWith(Suite.class)
@Suite.SuiteClass({CalculatorTest.class,SquareTest.class
})
public class AllCalcculatorTests{//没有内容没关系
}

参数化测试

如果待测试的输入和输出是一组数据:

  • 可以把测试数据组织起来
  • 用不同的测试数据调用相同的测试方法
  • 参数必须由静态方法data()返回
  • 返回类型为Collection<Object[]>
  • 静态方法必须标记为@Parameters
  • 测试类必须标记为@RunWith()
  • 构造方法参数必须和测试参数对应
//测试类必须标记为@RunWith(Patameterized.class)
@RunWith(Parameterized.class)
public class AbsTest{//参数必须由静态方法data()返回//返回类型为Collection<Object[]>//静态方法必须标记为@Patameters@Parameterspublic static Collection<?> data(){return Arrays.asList(new Object[][]{{0,0},{1,1},{-1,1}});}int input;int expected;//构造方法参数必须和测试参数对应public AbsTest(int input,int expected){this.input = input;this.expected = expected;}@Testpublic void testAbs(){int r = Math.abs(this.input);Assert.assertEquals(this.expected,r);}
}

超时测试

  • @Time(timeout = 1000)可以设置超时
  • timeout单位时毫秒
  • 超时测试不能取代性能测试和压力测试
//计算圆周率
//PI/4 = 1 - 1/3  + 1/5 - 1/7 + 1/9 -…
public class PI {//PI/4 = 1 - 1/3  + 1/5 - 1/7 + 1/9 -…//PI = 4 - 4/3 + 4/5 - 4/7 + 4/9 -...public double calculate(int count){double sum = 0;boolean positive = true;int n = 0;for (int i = 1;;i += 2){sum = sum + (positive ? 4.0 : -4.0)/i;positive = !positive;n++;if(n == count){break;}}return sum;}
}
public class PITest {PI pi;@Beforepublic void setUp() {pi = new PI();}@Afterpublic void tearDown() {pi = null;}//超时时间为100ms@Test(timeout = 100)public void test1k(){//计算1000次double r = pi.calculate(1000);assertEquals(3.14,r,0.01);}//超时时间为500ms@Test(timeout = 500)public void test1m(){//计算1百万次double r = pi.calculate(1000000);assertEquals(3.1416,r,0.0001);}//超时时间为500ms@Test(timeout = 500)public void test100m() {//计算10亿次double r = pi.calculate(1000000000);assertEquals(3.14159,r,0.00001);}
}

示例

/*
填写快递单时通常需要确定接收人的姓名、手机号和地址。其中要求手机号是11位数字字符,地址为字母开头的10个(含10)以内字母或字母数字共同组成。填写正确则提示“OK”,否则根据实际情况提示“**不符合要求”(**为手机号或地址),退出。编写程序实现此快递单信息的输入,并设计测试数据进行判定覆盖测试。输入数据打印出“输入手机号:”、“输入地址:”。
*/
public static main(String[]args){Scanner sc = new Scanner(System.in);System.out.println("请输入收件人手机号");String phone = sc.nextLine();System.out.println("请输入收件人地址");string address = sc.nextLine();boolean mphone = phone.matches("^\\d{11})$");boolean maddress = address.matches("^[a-zA-Z][a-zA-Z0-9]*$");if(!phmone){System.out.println("手机号不符合要求");}else if(!maddress){System.out.println("地址不符合要求");}else{System.out.println("OK");}
}
@RunWith(Parameterized.class)
public class ProgramTest(){private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();private final PrintStream originalOut = System.out;static Program program;String phone,address,expected;@Beforepublic void setUp(){program = new Program();System.setOut(new PrintStream(outContent));String inputMessage = phone + "\r\n" + address +"\r\n";System.setIn(new ByteArrayInputStream(inputMessage.getBytes()));}@Parameterspublic static Collection data(){return Array.asList(new Object[][]{{ "12345678900", "Asdfg12345", "OK" },{ "12345678900", "Asdfg12345a", "地址不符合要求" }, { "123456789001", "Asdfg12345", "手机号不符合要求" } })}public ProgramTest(String phone,String address,String expected){this.phone=phone;this.address=address;this.expected=expected;}@Testpublic void testMain(){program.main(null);String result = outContent.toString().split("\r\n")[2];assertThat(result,is(expected));}
}
@Test
public void test1001(){ByteArrayOutputStream outContent = new ByteArrayOutputStream();printStream originalout = System.out;Program progaram = new Program();System.setOut(new PrintStream(outContent));String inputMessage = "12345678900" + "\r\n" + "Asdfg12345" + "\r\n";System.setIn(new ByteArrayInputStream(inputMessage.getBytes()));program.main(null);String result = outContent.toString().split("\r\n")[2];assertThat(result,is("OK"));
}

相关文章:

JUnit

Junit 简介 JUnit是一个开源的java单元测试框架&#xff0c;它是XUnit测试体系架架构的一种体现 是Java语言事实上的标准单元测试库真正的优势来自于JUnit所采作用的思想和技术&#xff0c;而不是框架本身。推动了单元测试、测试先行的编程和测试驱动的开发JUnit衍生了许多xUn…...

MySQL学习笔记4-乐观锁和悲观锁

1.定义 乐观锁和倍灌水是并发控制采用的技术手段&#xff0c;确保当多个数位同时对数据中同一数据存取时&#xff0c;不会破坏事物的隔离性、统一性和数据库统一性 乐观锁 假定不会发生并发冲突&#xff0c;只在提交操作时检测是否违反数据完整性 实现方式&#xff1a; 记录…...

踩大坑:json格式存储wav二进制内容

需求描述&#xff1a; 需要将wav音频文件以二进制的形式读出&#xff0c;存放到 json 中&#xff0c;发送post请求到服务&#xff0c;服务解析json&#xff0c;得到二进制内容后放进ASR模型得出转录结果。 记一次坑&#xff1a; # 将wav以二进制形式读出存放到json中 f ope…...

加入CSDN的一年,我收获了这些……

加入CSDN的一年&#xff0c;我收获了这些……加入CSDN的一年&#xff0c;我收获了这些……加入CSDN的一年&#xff0c;我收获了这些…… &#x1f680;&#x1f680;时光如白驹过隙般&#xff0c;飞逝而过。一转眼&#xff0c;我就已经是一名大二的学生了&#xff0c;也已经在…...

【Python学习笔记】44.Python3 MongoDB和urllib

前言 本章介绍Python的MongoDB和urllib。 Python MongoDB MongoDB 是目前最流行的 NoSQL 数据库之一&#xff0c;使用的数据类型 BSON&#xff08;类似 JSON&#xff09;。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动&#xff0c;这里我们使用 PyMongo 驱动来连接。…...

LVS中的keepalived高可用

文章目录前言一、Keepalived简介二、keepalived工作原理三、配置文件四、实验1.某台Real Server down2.LVS本身down实验过程&#xff1a;五、代码详细演示整体过程调度器安装软件、设置测试keepalived对后端RS的健康检测backup服务主机设置前言 一、Keepalived简介 Keepalived是…...

【Vue3】组件数据懒加载

组件数据懒加载-基本使用 目标&#xff1a;通过useIntersectionObserver优化新鲜好物和人气推荐模块 电商类网站&#xff0c;尤其是首页&#xff0c;内容有好几屏&#xff0c;而如果一上来就加载所有屏的数据&#xff0c;并渲染所有屏的内容会导致首页加载很慢。 数据懒加载&a…...

基于 SmartX 分布式存储的 iSCSI 与两种 NVMe-oF 技术与性能对比

作者&#xff1a;深耕行业的 SmartX 金融团队本文重点SmartX 分布式块存储 ZBS 提供 2 种存算分离架构下的数据接入协议&#xff0c;分别是 iSCSI 和 NVMe-oF。其中&#xff0c;iSCSI 虽然具有很多优势&#xff0c;但不适合支持高性能的工作负载&#xff0c;这也是 SmartX 选择…...

Anaconda 安装 Pytorch

下载Anaconda,最新版本的即可,默认安装,最好不要安装在C盘,否则后面C盘容量会很大。 安装Pytorch 打开 Anaconda Prompt ,先切换镜像源为国内清华镜像源,这样安装包的时候下载速度会快一些,也容易成功一些。 在 Anaconda Prompt 命令行依次输入以下四条命令切换到清华镜…...

从零开始使用MMSegmentation训练Segformer

从零开始使用MMSegmentation训练Segformer 写在前面&#xff1a;最新想要用最新的分割算法如&#xff1a;Segformer or SegNeXt 在自己的数据集上进行训练&#xff0c;但是有不是搞语义分割出身的&#xff0c;而且也没有系统的学过MMCV以及MMSegmentation。所以就折腾了很久&am…...

会利用信息差赚钱的人才是聪明人

毕业后找不到工作&#xff0c;穷到只剩下时间&#xff0c;大小做了20多份副业兼职&#xff0c;终于找到了可靠的渠道&#xff0c; 我是专科生&#xff0c;学历不好&#xff0c;专业拉胯。毕业后&#xff0c;我找了两三份工作。要么工资太低&#xff0c;只能交房租&#xff0c;…...

【机器学习】Adaboost

1.什么是Adaboost AdaBoost&#xff08;adapt boost&#xff09;&#xff0c;自适应推进算法&#xff0c;属于Boosting方法的学习机制。是一种通过改变训练样本权重来学习多个弱分类器并进行线性结合的过程。它的自适应在于&#xff1a;被前一个基本分类器误分类的样本的权值会…...

深度学习神经网络基础知识(二)权重衰减、暂退法(Dropout)

专栏&#xff1a;神经网络复现目录 深度学习神经网络基础知识(二) 本文讲述神经网络基础知识&#xff0c;具体细节讲述前向传播&#xff0c;反向传播和计算图&#xff0c;同时讲解神经网络优化方法&#xff1a;权重衰减&#xff0c;Dropout等方法&#xff0c;最后进行Kaggle实…...

[面试直通版]网络协议面试核心之HTTP,HTTPS,DNS-DNS安全

点击->计算机网络复习的文章集<-点击 目录 典型问题&#xff1a; 部分现象 DNS劫持 DNS欺骗 DDoS攻击 典型问题&#xff1a; 什么是DNS劫持&#xff0c;DNS欺骗&#xff0c;是什么原理如何防范DNS攻击&#xff1f; 部分现象 错误域名解析到纠错导航页面错误域名解析…...

【OJ】A+B=X

&#x1f4da;Description: 数列S中有n个整数&#xff0c;判断S中是否存在两个数A、B&#xff0c;使之和等于X。 ⏳Input: 第一行为T&#xff0c;输入包括T组测试数据。 每组数据第一行包括两个数字n和X&#xff0c;第二行有n个整数&#xff0c;表示数列S&#xff0c;(1&l…...

Python实现性能自动化测试,还可以如此简单

Python实现性能自动化测试&#xff0c;还可以如此简单 目录&#xff1a;导读 一、思考❓❔ 二、基础操作&#x1f528;&#x1f528; 三、综合案例演练&#x1f528;&#x1f528; 四、总结&#x1f4a1;&#x1f4a1; 写在最后 一、思考❓❔ 1.什么是性能自动化测试? 性…...

Leetcode力扣秋招刷题路-0080

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 80. 删除有序数组中的重复项 II 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长…...

Java实现JDBC工具类DbUtils的抽取及程序实现数据库的增删改操作

封装DbUtils 工具类 不知道我们发现没有&#xff0c;不管是对数据库进行查询&#xff0c;还是标准的JDBC 步骤&#xff0c;其开端都是先实现JDBC 的加载注册&#xff0c;接着是获取数据库的连接&#xff0c;最后都是实现关闭连接&#xff0c;释放资源的操作。那我们何不直接把…...

【docker】拉取镜像环境报错解决#ERROR: Get https://registry-1.docker.io/v2/

&#x1f341;博主简介   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录问题报错原因解决方法问题 ERROR…...

java中NumberFormat 、DecimalFormat的介绍及使用,java数字格式化,BigDecimal数字格式化

文章目录前言一、NumberFormat1、概述2、实例化方法3、货币格式化4、百分比格式化5、NumberFormat的坑5.1、不同的格式化对象处理相同数值返回结果不同问题源码分析&#xff1a;二、DecimalFormat1、概述2、常用方法3、字符及含义0与#的区别分组分隔符的使用“%” 将数字乘以10…...

2023什么是分销商城系统?营销,核心功能

大家好&#xff0c;我是你们熟悉而又陌生的好朋友梦龙&#xff0c;一个创业期的年轻人 分销商城是指由网络营销运营商提供的&#xff0c;用于协助供给商搭建、管理及运作其网络销售渠道&#xff0c;协助分销商获取货源渠道的平台。简单来说&#xff0c;就是企业应用无线裂变分…...

天翼数字生活C++客户端实习

面试C客户端实习的岗位&#xff0c;相对不难 面试官&#xff1a;实习主要做的是国产操作系统下的应用&#xff0c;主要做的是视频监控、安防相关的工具&#xff0c;具体就是一个叫做 天翼云眼的软件&#xff0c;目前在windows下和电视下都有对应的应用&#xff0c;就是现在想在…...

Java 接口

文章目录1、接口的概念2、接口的定义3、接口的使用4、接口和抽象类1、接口的概念 类是一种具体的实现体&#xff0c;而接口定义了一种规范&#xff08;抽象方法&#xff09;&#xff0c;接口定义了某一批类所需要遵循的规范&#xff0c;接口不关心类内部的属性和方法的具体实现…...

【React】react-router 路由详解

&#x1f6a9;&#x1f6a9;&#x1f6a9; &#x1f48e;个人主页: 阿选不出来 &#x1f4a8;&#x1f4a8;&#x1f4a8; &#x1f48e;个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记. &#x1f4a8;&#x1f4a8;&#x1f4a8; &#x1f48e;目…...

DaVinci 偏好设置:系统 - 内存和 GPU

偏好设置 - 系统/内存和 GPUPreferences - System/Memory and GPU内存和 GPU Memory and GPU 选项卡提供了内存配置以及 GPU 配置的相关设置。内存配置Memory Configuration系统内存System Memory列出了所用电脑的总的可用内存。限制 Resolve 内存使用到Limit Resolve memory u…...

视频知识点(22)- 教你认清楚YUV420P和YUV420SP的真正差异在哪里

*《音视频开发》系列-总览* 前言 在视频技术领域,存在着非常多的颜色空间模型,YUV颜色空间就是其中之一。我们没有必要把所有的颜色空间都搞明白,只需要关注自己所从事的领域的常用颜色空间模型即可,同样,YUV颜色空间模型也有非常多的子类型,我们也没有必要都搞得清清楚楚…...

企业电子招标采购系统源码Spring Cloud + Spring Boot + MybatisPlus + Redis + Layui

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…...

面试常问-Alpha测试和Beta测试

Alpha测试 Alpha测试是一种验收测试&#xff0c;在识别典型用户可能执行的任务并对其进行测试之前&#xff0c;执行该测试是为了识别所有可能的问题和错误。 尽可能简单地说&#xff0c;这种测试之所以被称为alpha&#xff0c;只是因为它是在软件开发的早期、接近开发结束时和…...

html理论基础

组织&#xff1a;中国互动出版网&#xff08;http://www.china-pub.com/&#xff09;RFC文档中文翻译计划&#xff08;http://www.china-pub.com/compters/emook/aboutemook.htm&#xff09;E-mail&#xff1a;ouyangchina-pub.com译者&#xff1a;黄俊&#xff08;hujiao hj_c…...

【安卓开发】数据存储全方案--详解持久化技术

读书笔记系列&#xff1a;第一行代码 Android 6.1 持久化技术简介 三种数据持久化方式&#xff1a;文件存储、SharedPreference存储以及数据库存储&#xff0c;除此之外还可以存储在SD卡中&#xff08;不安全&#xff09; 6.2 文件存储 该方法不对存储的内容做格式化处理都…...

国外移民公司网站设计/中国最大网站排名

远程Linux服务器&#xff0c;报Host key verification failed错误。问题&#xff1a;使用其他电脑登录远程Linux服务器&#xff0c;可以登录&#xff0c;但其中一台电脑登录时报该错误。原因&#xff1a;是因为登录服务器时主机会把它的服务器登录标识证书记录下来&#xff0c;…...

网站后台怎么/站长网站优化公司

一、方法重载&#xff1a; 1.两个函数同名&#xff0c;就互相构成方法的重载关系 2.重载的函数&#xff0c;必须跟其他函数之间具有不同的参数类型或参数个数 二、字段与属性 类的字段&#xff1a; 类里面是可以直接定义变量的&#xff0c;这些变量就叫类的字段&#xff0c;也叫…...

百度蜘蛛抓取网站/公司网站建设费

abstractclassPerson{publicintage;publicStringname;publicStringoccupation;//publicPerson()//这里应该不会被调用吧构造方法只会调用一个呀~为什么这里去掉就报错了求大哥指教指教...abstract class Person{public int age;public String name;public String occupation;//…...

网盘做网站空间/网站做外链平台有哪些

系统集成是指通过结构化的综合布线系统和计算机网络技术&#xff0c;将各个分离的设备&#xff08;如个人电脑&#xff09;、功能和信息等集成到相互关联的、统一和协调的系统之中&#xff0c;使资源达到充分共享&#xff0c;实现集中、高效、便利的管理&#xff0c;以发挥整体…...

网站定制论文1500字左右/推广公司产品

问题&#xff1a;我在视图画的图象或者文字&#xff0c;当窗口改变后为什么不见了&#xff1f;OnDraw()和OnPaint()两个都是解决上面的问题&#xff0c;有什么不同&#xff1f; 答&#xff1a;OnDraw()和OnPaint()好象兄弟俩&#xff0c;因为它们的工作类似。至于不见了的问题…...

中国做网站的公司/关键词搜索优化公司

Android开发过程中&#xff0c;对TextView会用得非常多&#xff0c;字体颜色渐变或增加很多色彩. 这里说三种渐变方式&#xff1a; 一、LinearGradient 1)继承 TextView&#xff0c;重写 onLayout 方法后设置 Shader&#xff0c;也可再ondraw中处理 public class GradientTe…...