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

软件测试之单元测试

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快

一、何为单测

测试有黑盒测试和白盒测试之分,黑盒测试顾名思义就是我们不了解盒子的内部结构,我们通过文档或者对该功能的理解,指定了相应的输入参数,然后判断得出的结果是否正确。普通的用户、开发、QA都可以进行黑盒测试。

白盒测试与之相反,需要了解到内部的实现细节,一般是由开发人员自己来进行的,是基于对代码逻辑结构、各个关联方法了解基础上进行的。

白盒测试主要有 2 种

  • 静态代码分析:Findbugs、Sonarqube
  • 动态测试:单元测试

单元测试属于白盒测试里面的动态测试

二、单测的意义

2.1 解决问题的成本

测试金字塔,是单测中一张经典的图片。测试级别简单可以简单分为下面三类,详细的话可以归结为:单元测试、接口测试、集成测试、系统测试、验收测试。

如果发现问题,在金字塔越底层的阶段,解决问题的速度是越快的。

  • 本地开发环境发现问题:看几眼代码或者 debug 下就能定位出来了。
  • 生产环境发现问题:找日志(可能还没有输出),查数据库(可能没权限)。本地能复现的话还好,复现不了的话干着急。


2.2 维护系统的稳定性

我代码已经写好了挺久了,线上也运行一段时间了,还有必要补充单测吗?感觉单测写了一堆并没有发现问题,不知道价值点在哪。

  1. 校验你当前方法的正确性。
  2. 长时间保证你这个方法的稳定性,在往后需求的变更开发中,可能其他功能点影响到了这个方法,此时你的单测能很快帮你检查出来。
  3. 单测能够在你项目需要重构的时候,勇敢大步的往前走。与其反反复复修改问题,系统摇摇欲坠的,不如多花点时间优化代码,写写单测。

2.3 单测与持续集成的融合

单测 + CICD = 自动化测试

每次打包的时候自动跑单测用例,有问题快速反馈。没问题的代码才可以触发部署到对应的环境中。避免测试不足的代码提交到相关环境,导致服务用不了,测试人员一顿恼火。

三、单测拦路虎

1.框架繁多

新手对单测的框架没有意识,自己可能引用了一种, 其它框架 sdk 里面包含了另一种,比如 spring 的 framework 可能本身版本也五花八门,junit4 junit5 都有,使用的时候没注意乱用。

用了 junit5 写的用例,然后用 junit4 的 @Ignore 语法要去忽略这个单测,显然不行,因为在 junit5 对应的语法是 @Disabled

@Injectable @MockMethod @Mock @Test … 迷茫

2.缺少理论的实践

3.对单测的理念认同不够,赶鸭子上架,内心其实是抵触的。

4.用例泛泛而写,没有遵守用例核心三步骤:mock 数据 -> 方法触发 -> 结果校验

5.为了覆盖率而写的单测

6.为了证明你方法是对的而写的单测(单测后面补的,单测里面方法触发了就算写完了,不是抱着验证的态度对所有结果进行充分细致的校验)

7.代码逻辑太复杂单测太难写

可以在写单测的过程,推动部分方法的重构。如果是新代码可以用 TDD(测试驱动开发) 理念,先写单测再写业务代码,这样实现起来的业务代码比较能做到高内聚,低耦合。

8.业务压力太大,单测太耗时

单测代码编写时间:业务代码编写时间 = 2~3:1,所以如果公司决定了写单测就同时也要给与这部分的时间。不能即催着业务上线,又催着单测达标,特别是前期在对单测还不够熟悉的基础上。

9.单测维护成本

单测也是需要维护的,case 多了后会发现,一有业务调整,不单单业务代码要调,单测也要调整,否则 case 会失败。

四、单测框架说明

1.Jmock

  • 网站:jMock - An Expressive Mock Object Library for Java
  • 不能对静态方法Mock

2.Mockito

  • 官方主页 http://code.google.com/p/mockito/
  • 不能对静态方法Mock

3.JMockit

  • http://jmockit.github.io/
  • 功能强大,可以 mock 静态方法

4.EasyMock

  • 官方主页 http://www.easymock.org/

5.testNg

  • TestNG可以进行单元测试,功能测试,端到端测试,集成测试等。
  • 需要一个额外的xml配置文件,配置测试的class、method甚至package

6.Spock

  • https://tech.meituan.com/tags/spock.html
  • BDD 的单测写法,Groovy 语法,快速,但是跟我们 java 的编码习惯不大一样。无法 mock 静态方法。

7.TestableMock

  • 文档:https://alibaba.github.io/testable-mock/#/zh-cn/doc/setup
  • TestableMock 和 JMockit 底层一致,使用的是 “运行时字节码修改” 技术,在单元测试启动时就扫描测试类和被测类的字节码,完成 Mock 方法的替换。

8.junit4

  • Java领域内最为流行的单元测试框架

9.junit5

  • JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
  • JUnit Platform: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。
  • JUnit Jupiter: JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行。
  • JUnit Vintage: 由于JUint已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。

10.Springtest

https://www.cnblogs.com/itplay/p/10101260.html

兼容多种测试引擎,便捷傻瓜,但是有下面几个问题

  • 可能存在多次启动 spring 容器
  • 一次 case 可能加载很多不需要的 bean ,导致速度很慢

11.总结
框架非常多,选择框架的时候可以从下面几个点考虑:
12.语法好写吗,文档全吗
13.能 mock 静态类,静态方法吗

  • 推荐 = junit5 + ( jmockit | testableMock),有冒险精神的可以尝试 Spock,速度快但是静态方法的 mock 需要借助其它工具。

Fastjunit = junit5 + jmockit + 测试工具集

单测框架总类繁多,本人很多都没有了解到位,以上总结仅为一家之言,兼听则明。

五、最佳实践

5.1. 理论知识要记牢

- 用例要轻量,执行速度要够快
- 执行过后没有痕迹
- 不依赖特点环境,随处都可以执行
- 校验要全面

5.2. 测试代码模板

单测的代码跟业务代码一样,需要易于阅读,方便维护。

再复杂的用例都要清晰得看出下面 3 个步骤
1. 上下文设置:参数模拟,mock 无用服务
2. 触发测试用例执行
3. 结果断言
/*** Given 给定上下文【初始化数据,Mock 外部调用】*/
new Expectations(EsClient.class) {{EsClient.createDoc(withInstanceOf(SimpleDocVo.class), withInstanceOf(PipelineJobJunit.class));result = "{}";times = 1;}
};
/*** 执行测试代码*/
RestResponse restResponse = callBackController.junitCallBak(jenkinsJunitVo);/*** Assert 要足够细致*/
Assertions.assertThat(restResponse).hasFieldOrPropertyWithValue("code", 0);

5.3 TDD 测试驱动开发

好的代码编写测试用例的时候是比较顺畅的,如果写单测的时候觉得目标代码很难测试,这时候大概率是目标代码编写不合理,需要优化重构下。另一方面,如果在写业务代码的时候先写好单测框架,此时能反向推动你写成比较好的代码。

5.3.1 松散代码

业务逻辑平铺在一个方法里面,此时你的单测不好关注主流程,也很难 mock 其它无用的东西(因为比较多)。此时为了让我们的单测好写,可以反向推动业务代码朝着高内聚低耦合的方向重构。

下面红框中的逻辑可以抽出来,主流程就清晰很多,用例也好写很多。

5.3.2 不稳定的代码

此方法里读取当前系统时间并根据该值返回结果。Datetime.now 是一个隐藏的动态变量,整个方法的输出结果依赖于 datetime 的时间。

public static string GetTimeOfDay()
{DateTime time = DateTime.Now;if (time.Hour >= 0 && time.Hour < 6>= 6 && time.Hour < 12>= 12 && time.Hour < 18 xss=removed>= 0 && dateTime.Hour < 6>= 6 && dateTime.Hour < 12>= 12 && dateTime.Hour < 18 xss=removed xss=removed xss=removed> StringUtil.isNotEmpty(simpleDocVo.getId()));Assertions.assertThat(document).hasFieldOrPropertyWithValue("pipelineJobId", jenkinsJunitVo.getUapJobId()).hasFieldOrPropertyWithValue("status", jenkinsJunitVo.getStatus()).hasFieldOrPropertyWithValue("allCoverage", jenkinsJunitVo.getAllCoverage()).hasFieldOrPropertyWithValue("newCoverage", jenkinsJunitVo.getNewCoverage()).hasFieldOrPropertyWithValue("testRun", jenkinsJunitVo.getTestRun()).hasFieldOrPropertyWithValue("testFailure", jenkinsJunitVo.getTestFailure()).hasFieldOrPropertyWithValue("testSkipped", jenkinsJunitVo.getTestSkipped());}
};

5.4造数据

你还在一个个属性的添加吗?

@Test
public void webhookTestWebhook() {OtptestWebhookQueryDTO dto = new OtptestWebhookQueryDTO();dto.setApp("uap");dto.setEnv("test");dto.setJobId("xxx");dto.setVersion("v2.2");xxx
}

http://fastjunit.kubeclub.cn/test-basic/dataProvider/

Fastjunit 的数据生成器,任意给个 Bean 对象,自动的根据字段属性帮你随机产生相关数据。也支持数组对象的随机生成。可以节约不少时间。

5.5参数化测试

多种分支场景,使用参数化的测试可以让你的用例更简单。

@ParameterizedTest(name = "{0} + {1} = {2}")
@CsvSource({"0,    1,   1","1,    2,   3","49,  51, 100","1,  100, 101"
})
void add(int first, int second, int expectedResult) {Calculator calculator = new Calculator();assertEquals(expectedResult, calculator.add(first, second),() -> first + " + " + second + " should equal " + expectedResult);
}

5.6 数据库测试 - H2

H2 是一个内存数据,H2 仅仅只支持简单标准的 SQL 语法,如果各厂商特有的数据库引擎的特殊函数,可以使用 H2Function 扩展。

Fastjunit 同样对 H2 进行了一些封装:http://fastjunit.kubeclub.cn/db/h2/

5.7 并行测试

CICD 融入单测的过程,可能导致构建速度变慢,此时如果你的测试是并行的话,能在一定程度提高执行的速度。

  • Junit5-parallel:
  • Surefire-parallel :http://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html

5.8 IDEA 快捷键

多了解些快捷键,在单测的过程中执行一些批量操作还是挺有效率的。如 bean 十几个、几十个属性,要批量赋值,批量校验的一些场景。

5.9 单测的范围

5.10 单测报告 - Jacoco

http://fastjunit.kubeclub.cn/test-basic/jacoco-report/

六、Jmockit 简单说明

6.1 示例

class ExampleTest {@Tested ServiceAbc tested;@Injectable DependencyXyz mockXyz;@Testvoid doOperationAbc(@Mocked AnotherDependency anyInstance) {new Expectations() {{anyInstance.doSomething(anyString); result = 123;AnotherDependency.someStaticMethod(); result = new IOException();}};tested.doOperationAbc("some data");new Verifications() {{ mockXyz.complexOperation(true, anyInt, null); times = 1; }};}
}
  1. 实例化和属性注入:@Tested 自动实例化 ServiceAbc 对象,并把 @Injectable DependencyXyz 属性自动注入到 tested 里面。
  2. 模拟期望:Expectations 内部的匿名方法会实现对象的模拟和期望。
 // anyInstance 对象的 doSomething 方法被调用的时候将返回 123// 收到的参数需要是任意的字符类型 anyString ,万一收到一个 int,就不会返回 123 了anyInstance.doSomething(anyString); result = 123;

6.2 @Capturing

@Mocked 一般是 mock 具体的对象,像一些接口或者基类,我们只知道具体的实现类,这种场景可以用 @Capturing。(例如:像一些权限校验,AOP 代理自动生成的场景)

 //权限类,校验用户没有权限访问某资源public interface IPrivilege {/*** 判断用户有没有权限* @param userId* @return 有权限,就返回true,否则返回false*/public boolean isAllow(long userId);
}
@Test
public void testCaputring(@Capturing IPrivilege privilegeManager) {
// 加上了JMockit的API @Capturing,
// JMockit会帮我们实例化这个对象,它除了具有@Mocked的特点,还能影响它的子类/实现类
new Expectations() {{// 对IPrivilege的所有实现类录制,假设测试用户有权限privilegeManager.isAllow(testUserId);result = true;}
};
// 不管权限校验的实现类是哪个,这个测试用户都有权限
Assert.assertTrue(privilegeManager1.isAllow(testUserId));
Assert.assertTrue(privilegeManager2.isAllow(testUserId));
}

6.3 参数的灵活匹配

在录制和验证阶段,一个对模拟方法或构造方法的调用参数做灵活的匹配。

1.any

最不严格的参数匹配,当然每个方法的参数都有类型的,还是要给定个恰当的参数类型。

new Expectations() {{abc.voidMethod(anyString, (List&lt;?&gt;) any);
}};

2.with

// 不为空即可
abc.voidMethod("str", (List&lt;?&gt;) withNotNull());// 需要是什么类型,需要包含 xyz 字符
abc.stringReturningMethod(withSameInstance(item), withSubstring("xyz"));// 前缀需要是 abc
mock.doSomething(anyInt, true, withPrefix("abc"));// 更多查看接口文档

6.4 调用次数约束/验证

// 该方法最少被调用 2 次
abc.voidMethod(); minTimes = 2;// 被调用 1~5 次
abc.stringReturningMethod(); minTimes = 1; maxTimes = 5;// 最多被调用 1 次
abc.anotherVoidMethod(3); maxTimes = 1;

6.5 从调用方法中捕捉参数,并对参数进一步验证

new Verifications() {{double d;String s;mock.doSomething(d = withCapture(), null, s = withCapture());assertTrue(d > 0.0);assertTrue(s.length() > 1);
}};

七、结尾

单测相关的意义开头已经讲了,这边不重复总结,补充下下面 2 点。

1.麻烦事

  • 业务代码的改动单测要跟着改动,不要之前写了单测,后面业务调整导致已有单测失败了,就简单的给 ignore 了。
  • 要一开始就规划好单测,不要写好业务代码,后续补单测。已经稳定的代码,补单测的意义不大。

2.收获

  • 提升开发素养:不做 CRUD 程序员,单测的工作中会让你深入了解各个代码甚至中间件的实现逻辑,深入底层了解内部实现。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

​这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

相关文章:

软件测试之单元测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、何为单测 测试有黑盒测试和白盒测试之分&#xff0c;黑盒测试顾名思义就是我们不了解盒子的内部结构&#xff0c;我们通过文档或者对该功能的理解&#xff0c…...

vscode+编程AI配置、使用说明

文章目录 [toc]1、概述2、github copilot2.1 配置2.2 使用文档2.3 使用说明 3、文心快码&#xff08;Baidu Comate&#xff09;3.1 配置3.2 使用文档3.3 使用说明 4、豆包&#xff08;MarsCode&#xff09;4.1 配置4.2 使用文档4.3 使用说明 5、通义灵码&#xff08;TONGYI Lin…...

007-spring-bean的相关配置(重要)

spring-bean的相关配置...

【唐叔学算法】第19天:交换排序-冒泡排序与快速排序的深度解析及Java实现

引言 排序算法是计算机科学中的基础问题&#xff0c;而交换排序作为其中一类经典的排序方法&#xff0c;因其简单直观的思想和易于实现的特点&#xff0c;在初学者中广受欢迎。交换排序的核心思想是通过不断交换相邻元素来达到排序的目的。本文将深入探讨两种典型的交换排序算…...

合并 Python 中的字典

合并 Python 中的字典 如何在 Python 中合并字典&#xff1f; 这取决于你对“合并”一词的具体定义。 在 Python 中使用 | 操作符合并字典 首先&#xff0c;让我们讨论合并字典的最简单方法&#xff0c;这通常已经足够满足你的需求。 以下是两个字典&#xff1a; >>…...

使用Python实现自动化文档生成工具:提升文档编写效率的利器

友友们好! 我的新专栏《Python进阶》正式启动啦!这是一个专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会找到: ● 深入解析:每一篇文章都将…...

uniapp使用live-pusher实现模拟人脸识别效果

需求&#xff1a; 1、前端实现模拟用户人脸识别&#xff0c;识别成功后抓取视频流或认证的一张静态图给服务端。 2、服务端调用第三方活体认证接口&#xff0c;验证前端传递的人脸是否存在&#xff0c;把认证结果反馈给前端。 3、前端根据服务端返回的状态&#xff0c;显示在…...

【JavaSE】【网络原理】初识网络

目录 一、网络互联二、局域网与广域网三、网络通信基础3.1 IP地址3.2 端口号3.3 网络协议3.4 五元组 四、协议分层4.1 OSI七层网络模型4.2 TCP/IP五层(四层)网络模型4.3 网络设备 五、网络数据通信基本流程。5.1 封装和分用5.2 简述过程 一、网络互联 网络互联&#xff1a; 网…...

鸿蒙之路的坑

1、系统 Windows 10 家庭版不可用模拟器 对应的解决方案【坑】 升级系统版本 直接更改密钥可自动升级系统 密钥找对应系统的&#xff08;例&#xff1a;windows 10专业版&#xff09; 升级完之后要激活 坑1、升级完后事先创建好的模拟器还是无法启动 解决&#xff1a;删除模拟…...

Python生日祝福烟花

1. 实现效果 2. 素材加载 2个图片和3个音频 shoot_image pygame.image.load(shoot(已去底).jpg) # 加载拼接的发射图像 flower_image pygame.image.load(flower.jpg) # 加载拼接的烟花图 烟花不好去底 # 调整图像的像素为原图的1/2 因为图像相对于界面来说有些大 shoo…...

Ubuntu环境 nginx.conf详解(二)

1、nginx.conf 结构详解&#xff1a; http 块&#xff1a;用于配置 HTTP 服务器的相关设置&#xff0c;包括处理 HTTP 和 HTTPS。 stream 块&#xff1a;用于配置 TCP/UDP 代理服务器&#xff0c;适用于需要进行四层负载均衡的情况。 ... # 全局块 events {...} …...

shardingsphere分库分表项目实践4-sql解析sql改写

为什么要sql解析重写&#xff1f; 如果我们的系统数据库实现了分表&#xff0c;那么我们的sql中表名需要根据参数动态确定&#xff0c;那么代码怎么写&#xff1f; 方案1&#xff1a; 自己手动拼接&#xff0c; 比如 update t_user_${suffix} , ${suffix} 作为一个变量传递…...

mysql数据库中,一棵3层的B+树,假如数据节点大小是1k,那这棵B+可以存多少条记录(2100万的由来)

在MySQL中&#xff0c;3层的B树可以存储的数据量取决于多个因素&#xff0c;包括页大小、每行数据的大小以及索引项的大小。以下是一个详细的计算过程&#xff1a; 一、假设条件 页大小&#xff1a;在InnoDB存储引擎中&#xff0c;B树的每个节点&#xff08;页&#xff09;大…...

Git 操作全解:从基础命令到高级操作的实用指南

文章目录 1.基本命令1.初始化仓库2.克隆远程仓库3.查看当前仓库状态4.查看提交日志5.添加文件到暂存区6.提交更改7.查看仓库的配置信息 2.分支操作1.查看所有分支2.创建新分支3.切换名称4.创建并切换到新分支5.删除分支6.查看当前分支 3.合并分支1.合并分支2.解决合并冲突 4.远…...

华院计算参与项目再次被《新闻联播》报道

12月17日&#xff0c;央视《新闻联播》播出我国推进乡村振兴取得积极进展。其中&#xff0c;华院计算参与的江西省防止返贫监测帮扶大数据系统被报道&#xff0c;该系统实现了由原来的“人找人”向“数据找人”的转变&#xff0c;有效提升监测帮扶及时性和有效性&#xff0c;守…...

从一次线上故障聊聊接口自动化测试

1、背景 3月初&#xff0c;运营同事配置了个还未上线的页面到网站首页 banner&#xff0c;导致用户点了报错。尽管这次很明确是运营人为操作失误引起的故障&#xff0c;但过往此类核心页面的访问异常&#xff0c;我们已不是第一次遇见。 从平台整体利益触发&#xff0c;我们各…...

Element-ui的使用教程 基于HBuilder X

文章目录 1.Element-ui简介2.使用HBuilderX 创建一个基于Vue3的项目 &#xff08;由于是使用的基于Vue3的Element-ui&#xff09;3.安装element-ui4.在项目里完全引用element-ui5.引用组件6.运行项目 1.Element-ui简介 Element&#xff0c;一套为开发者、设计师和产品经理准备…...

Chapter 03 复合数据类型-1

1.列表 Python内置的一种有序、可变的序列数据类型&#xff1b; 列表的定义&#xff1a; [ ]括起来的逗号分隔的多个元素组成的序列 列表对象的创建&#xff1a; &#xff08;1&#xff09;直接赋值 >>> list1 []#创建一个空列表赋值给list1 >>> list…...

【Python知识】Python面向对象编程知识

Python面向对象编程知识 概述1. 类&#xff08;Class&#xff09;2. 对象&#xff08;Object&#xff09;3. 封装&#xff08;Encapsulation&#xff09;4. 继承&#xff08;Inheritance&#xff09;5. 多态&#xff08;Polymorphism&#xff09;6. 抽象&#xff08;Abstractio…...

CSharp: Oracle Stored Procedure query table

存储过程查询postgreSQL,Oracle 和sql server,Mysql 有区别。程序调用也是有区别。 oracle sql script: CREATE OR REPLACE PROCEDURE procSelectSchool(paramSchoolId IN char,p_cursor OUT SYS_REFCURSOR ) AS BEGINOPEN p_cursor FORSELECT *FROM SchoolWHERE SchoolId p…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...