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 匹配器
注意事项
-
必须导入JUnit4.4之后的版本才能使用assertThat方法
-
不需要继承TestCase类,但是需要测试方法前加
@Test
-
需要导入Hamcrest类库:hamcrest-core-1.3.0.jar和hamcrest-library-1.3.0.jar
-
在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方法:
- 实例化CalculatorTest
- 执行@Before方法
- 执行@Test方法
- 执行@After方法
使用@Before和@After可以保证:
- 单个@Test方法执行前会创建新的XxxTest实例,实例变量的状态不会传递给下一个@Test方法
- 单个@Test方法执行前后会执行@Before和@After方法
@BeforeClass和@AfterClass静态方法:
- 在执行所有@Test方法前执行@BeforeClass静态方法
- 执行所有测试
- 在执行所有@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默认的运行器
-
默认运行器
@RunWith(Junit4.class)
-
参数化运行器
- @RunWith(Patammeterized.class)配合@Patameters使用junit的参数化功能
- @RunWith(Suite.class)
- @SuiteClass({ATest.class,BTest.class,CTest.class})
- 配合使用测试集功能
-
兼容junit3.8的运行器
@RunWith(JUnit38ClassRunner.class)
-
其他运行器
例如@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());}
}
实现步骤
- 为类指定运行器:@RunWith(Parameterized.class)
- 创建提供数据的方法,加上@Parameters注解,方法必须是static的,并且返回一个集合Collection;
- 在测试类的构造方法中为各个参数赋值
- 编写测试方法,它会根据参数的组数来运行测试多次
- 注意
- 要为这种测试专门生成一个新的类
- 要为这个类指定一个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单元测试框架,它是XUnit测试体系架架构的一种体现 是Java语言事实上的标准单元测试库真正的优势来自于JUnit所采作用的思想和技术,而不是框架本身。推动了单元测试、测试先行的编程和测试驱动的开发JUnit衍生了许多xUn…...
MySQL学习笔记4-乐观锁和悲观锁
1.定义 乐观锁和倍灌水是并发控制采用的技术手段,确保当多个数位同时对数据中同一数据存取时,不会破坏事物的隔离性、统一性和数据库统一性 乐观锁 假定不会发生并发冲突,只在提交操作时检测是否违反数据完整性 实现方式: 记录…...
踩大坑:json格式存储wav二进制内容
需求描述: 需要将wav音频文件以二进制的形式读出,存放到 json 中,发送post请求到服务,服务解析json,得到二进制内容后放进ASR模型得出转录结果。 记一次坑: # 将wav以二进制形式读出存放到json中 f ope…...

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

【Python学习笔记】44.Python3 MongoDB和urllib
前言 本章介绍Python的MongoDB和urllib。 Python MongoDB MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON)。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 PyMongo 驱动来连接。…...

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

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

基于 SmartX 分布式存储的 iSCSI 与两种 NVMe-oF 技术与性能对比
作者:深耕行业的 SmartX 金融团队本文重点SmartX 分布式块存储 ZBS 提供 2 种存算分离架构下的数据接入协议,分别是 iSCSI 和 NVMe-oF。其中,iSCSI 虽然具有很多优势,但不适合支持高性能的工作负载,这也是 SmartX 选择…...
Anaconda 安装 Pytorch
下载Anaconda,最新版本的即可,默认安装,最好不要安装在C盘,否则后面C盘容量会很大。 安装Pytorch 打开 Anaconda Prompt ,先切换镜像源为国内清华镜像源,这样安装包的时候下载速度会快一些,也容易成功一些。 在 Anaconda Prompt 命令行依次输入以下四条命令切换到清华镜…...

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

会利用信息差赚钱的人才是聪明人
毕业后找不到工作,穷到只剩下时间,大小做了20多份副业兼职,终于找到了可靠的渠道, 我是专科生,学历不好,专业拉胯。毕业后,我找了两三份工作。要么工资太低,只能交房租,…...

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

深度学习神经网络基础知识(二)权重衰减、暂退法(Dropout)
专栏:神经网络复现目录 深度学习神经网络基础知识(二) 本文讲述神经网络基础知识,具体细节讲述前向传播,反向传播和计算图,同时讲解神经网络优化方法:权重衰减,Dropout等方法,最后进行Kaggle实…...
[面试直通版]网络协议面试核心之HTTP,HTTPS,DNS-DNS安全
点击->计算机网络复习的文章集<-点击 目录 典型问题: 部分现象 DNS劫持 DNS欺骗 DDoS攻击 典型问题: 什么是DNS劫持,DNS欺骗,是什么原理如何防范DNS攻击? 部分现象 错误域名解析到纠错导航页面错误域名解析…...

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

Python实现性能自动化测试,还可以如此简单
Python实现性能自动化测试,还可以如此简单 目录:导读 一、思考❓❔ 二、基础操作🔨🔨 三、综合案例演练🔨🔨 四、总结💡💡 写在最后 一、思考❓❔ 1.什么是性能自动化测试? 性…...
Leetcode力扣秋招刷题路-0080
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 80. 删除有序数组中的重复项 II 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长…...

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

【docker】拉取镜像环境报错解决#ERROR: Get https://registry-1.docker.io/v2/
🍁博主简介 🏅云计算领域优质创作者 🏅华为云开发者社区专家博主 🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 文章目录问题报错原因解决方法问题 ERROR…...

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

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...