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

【09】深入解析 Three.js 官网示例:下雪粒子特效与场景渲染的实现(webgpu_compute_particles_snow.html)

引言

Three.js 是一个强大的 JavaScript 库,用于在网页上创建和渲染 3D 场景。本文将深入分析一段 Three.js 官网示例代码,详细解释其实现思路和主要功能代码,帮助读者更好地理解和掌握 Three.js 的应用。官网代码地址:https://github.com/mrdoob/three.js/blob/master/examples/webgpu_compute_particles_snow.html

代码整体架构

代码主要实现了一个包含粒子特效、场景物体(如地板、树、茶壶等)的 3D 场景,并进行了碰撞检测、粒子计算更新、场景渲染以及后期处理等操作。整体分为初始化、更新计算、渲染等几个主要部分。

主要功能代码解析

初始化部分

init();
async function init() {// 相机设置camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 100);camera.position.set(20, 2, 20);camera.layers.enable(2);camera.lookAt(0, 40, 0);// 场景设置scene = new THREE.Scene();scene.fog = new THREE.Fog(0x0f3c37, 5, 40);// 灯光设置const dirLight = new THREE.DirectionalLight(0xf9ff9b, 9);// 灯光阴影相关设置dirLight.shadow.camera.near = 1;dirLight.shadow.camera.far = 30;//...更多阴影设置scene.add(dirLight);scene.add(new THREE.HemisphereLight(0x0f3c37, 0x080d10, 100));// 碰撞相机和渲染目标设置collisionCamera = new THREE.OrthographicCamera(-50, 50, 50, -50, 0.1, 50);collisionCamera.position.y = 50;collisionCamera.lookAt(0, 0, 0);collisionCamera.layers.enable(1);collisionPosRT = new THREE.RenderTarget(1024, 1024);// 渲染目标纹理设置collisionPosRT.texture.type = THREE.HalfFloatType;//...更多纹理设置collisionPosMaterial = new THREE.MeshBasicNodeMaterial();collisionPosMaterial.fog = false;collisionPosMaterial.toneMapped = false;collisionPosMaterial.colorNode = positionWorld.y;// 粒子相关缓冲区设置const positionBuffer = instancedArray(maxParticleCount, 'vec3');const scaleBuffer = instancedArray(maxParticleCount, 'vec3');const staticPositionBuffer = instancedArray(maxParticleCount, 'vec3');const dataBuffer = instancedArray(maxParticleCount, 'vec4');// 粒子初始化计算const computeInit = Fn(() => {// 计算粒子初始位置、缩放等const position = positionBuffer.element(instanceIndex);const scale = scaleBuffer.element(instanceIndex);const particleData = dataBuffer.element(instanceIndex);// 随机数生成const randX = hash(instanceIndex);const randY = hash(instanceIndex.add(randUint()));const randZ = hash(instanceIndex.add(randUint()));position.x = randX.mul(100).add(-50);position.y = randY.mul(500).add(3);position.z = randZ.mul(100).add(-50);scale.xyz = hash(instanceIndex.add(Math.random())).mul(0.8).add(0.2);staticPositionBuffer.element(instanceIndex).assign(vec3(1000, 10000, 1000));particleData.y = randY.mul(-0.1).add(-0.02);particleData.x = position.x;particleData.z = position.z;particleData.w = randX;})().compute(maxParticleCount);// 场景物体添加const geometry = new THREE.SphereGeometry(surfaceOffset, 5, 5);const dynamicParticles = particle();const staticParticles = particle(true);scene.add(dynamicParticles);scene.add(staticParticles);const floorGeometry = new THREE.PlaneGeometry(100, 100);floorGeometry.rotateX(-Math.PI / 2);const plane = new THREE.Mesh(floorGeometry, new THREE.MeshStandardMaterial({color: 0x0c1e1e,roughness: 0.5,metalness: 0,transparent: true}));plane.material.opacityNode = positionLocal.xz.mul(0.05).distance(0).saturate().oneMinus();scene.add(plane);scene.add(tree());const teapotTree = new THREE.Mesh(new TeapotGeometry(0.5, 18), new THREE.MeshBasicNodeMaterial({color: 0xfcfb9e}));teapotTree.position.y = 18;scene.add(teapotTree);// 场景背景设置scene.backgroundNode = screenUV.distance(0.5).mul(2).mix(color(0x0f4140), color(0x060a0d));// 渲染器、统计工具、控制设置renderer = new THREE.WebGPURenderer({ antialias: true });renderer.toneMapping = THREE.ACESFilmicToneMapping;renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);renderer.setAnimationLoop(animate);stats = new Stats({precision: 3,horizontal: false});stats.init(renderer);controls = new OrbitControls(camera, renderer.domElement);// 控制参数设置controls.target.set(0, 10, 0);//...更多控制参数设置controls.update();// 后期处理设置const scenePass = pass(scene, camera);const scenePassColor = scenePass.getTextureNode();const vignette = screenUV.distance(0.5).mul(1.35).clamp().oneMinus();const teapotTreePass = pass(teapotTree, camera).getTextureNode();const teapotTreePassBlurred = gaussianBlur(teapotTreePass, vec2(1), 3);teapotTreePassBlurred.resolution = new THREE.Vector2(0.2, 0.2);const scenePassColorBlurred = gaussianBlur(scenePassColor);scenePassColorBlurred.resolution = new THREE.Vector2(0.5, 0.5);scenePassColorBlurred.directionNode = vec2(1);let totalPass = scenePass;totalPass = totalPass.add(scenePassColorBlurred.mul(0.1));totalPass = totalPass.mul(vignette);totalPass = totalPass.add(teapotTreePass.mul(10).add(teapotTreePassBlurred));postProcessing = new THREE.PostProcessing(renderer);postProcessing.outputNode = totalPass;await renderer.computeAsync(computeInit);window.addEventListener('resize', onWindowResize);
}

  • 相机与场景设置:创建了透视相机PerspectiveCamera,设置了视角、位置、看向点等参数。同时创建了场景Scene,并设置了雾效。
  • 灯光设置:添加了方向光DirectionalLight和半球光HemisphereLight,并对方向光的阴影进行了详细设置。
  • 碰撞检测相关设置:创建了正交相机OrthographicCamera用于碰撞检测,设置了渲染目标RenderTarget和材质MeshBasicNodeMaterial,用于获取碰撞位置信息。
  • 粒子初始化:通过instancedArray创建了多个粒子相关的缓冲区,用于存储粒子的位置、缩放等信息。computeInit函数计算粒子的初始位置、缩放和其他属性。
  • 场景物体添加:创建了粒子、地板、树、茶壶等物体,并添加到场景中。每个物体都有其特定的几何形状和材质设置。
  • 渲染器、统计和控制设置:创建了WebGPURenderer渲染器,设置了色调映射、像素比等参数。同时初始化了统计工具Stats和相机控制OrbitControls
  • 后期处理设置:通过pass函数获取场景和茶壶树的纹理节点,应用高斯模糊gaussianBlur等效果,最后通过PostProcessing组合这些效果。

更新计算部分

const surfaceOffset = 0.2;
const speed = 0.4;
const computeUpdate = Fn(() => {const getCoord = (pos) => pos.add(50).div(100);const position = positionBuffer.element(instanceIndex);const scale = scaleBuffer.element(instanceIndex);const particleData = dataBuffer.element(instanceIndex);const velocity = particleData.y;const random = particleData.w;const rippleOnSurface = texture(collisionPosRT.texture, getCoord(position.xz));const rippleFloorArea = rippleOnSurface.y.add(scale.x.mul(surfaceOffset));If(position.y.greaterThan(rippleFloorArea), () => {position.x = particleData.x.add(time.mul(random.mul(random)).mul(speed).sin().mul(3));position.z = particleData.z.add(time.mul(random).mul(speed).cos().mul(random.mul(10)));position.y = position.y.add(velocity);}).Else(() => {staticPositionBuffer.element(instanceIndex).assign(position);});
});
computeParticles = computeUpdate().compute(maxParticleCount);

computeUpdate函数用于更新粒子的位置。通过获取碰撞位置纹理信息,判断粒子是否在某个表面之上,从而决定粒子的运动方式。如果粒子在表面之上,根据一些随机和时间相关的计算更新粒子的位置;否则将粒子位置存储到静态位置缓冲区。

渲染部分

async function animate() {controls.update();scene.overrideMaterial = collisionPosMaterial;renderer.setRenderTarget(collisionPosRT);await renderer.renderAsync(scene, collisionCamera);await renderer.computeAsync(computeParticles);scene.overrideMaterial = null;renderer.setRenderTarget(null);await postProcessing.renderAsync();stats.update();
}

animate函数是动画循环的核心。在每一帧中,首先更新相机控制,然后设置场景的覆盖材质,通过碰撞相机渲染场景到碰撞位置渲染目标,接着计算粒子的更新,恢复场景的正常材质,最后进行后期处理的渲染,并更新统计信息。

总结

通过对这段 Three.js 代码的详细解析,我们了解了如何创建复杂的 3D 场景,包括相机、灯光、物体的设置,如何进行粒子特效的实现,以及碰撞检测、后期处理等功能。希望本文对你有帮助!

相关文章:

【09】深入解析 Three.js 官网示例:下雪粒子特效与场景渲染的实现(webgpu_compute_particles_snow.html)

引言 Three.js 是一个强大的 JavaScript 库,用于在网页上创建和渲染 3D 场景。本文将深入分析一段 Three.js 官网示例代码,详细解释其实现思路和主要功能代码,帮助读者更好地理解和掌握 Three.js 的应用。官网代码地址:https://g…...

电子价签会是零售界的下一个主流?【新立电子】

电子价签,作为一种能够替代传统纸质标签的数字显示屏,已经在零售行业中展现出其巨大的潜力。它具有实时更新、集中管理、高效节能的特点,实现价格的实时更新,大大减少更新价格的工作量和时间。为消费者带来更加便捷、准确的购物体…...

uniapp——App下载文件,保存、打开文件(二)

uniapp如何下载文件、保存、打开文件 时光荏苒,2024即将过去! 迈向2025,祝大家新的一年工作顺利、万事如意,少一点BUG,涨一点工资…↖(ω)↗ 文章目录 uniapp如何下载文件、保存、打开文件下载文件保存并打开文件处理 …...

如何轻松关闭 iPhone 上的 HEIC [HEIC 图像技巧]

您是否正在为关闭 iPhone 上的 HEIC 而烦恼?你不是一个人; Apple 的首选图像文件格式仍可能存在一些兼容性问题。当您与某人共享照片或尝试在Windows计算机上打开图像时,就会出现此问题。幸运的是,Apple 使关闭 HEIC iPhone 变得更加容易。 …...

库伦值自动化功耗测试工具

1. 功能介绍 PlatformPower工具可以自动化测试不同场景的功耗电流,并可导出为excel文件便于测试结果分析查看。测试同时便于后续根据需求拓展其他自动化测试用例。 主要原理:基于文件节点 coulomb_count 实现,计算公式:电流&…...

[paddle] 非线性拟合问题的训练

利用paddlepaddle建立神经网络,模拟有限个数据的非线性拟合 本文仍然考虑 f ( x ) sin ⁡ ( x ) x f(x)\frac{\sin(x)}{x} f(x)xsin(x)​ 函数在区间 [-10,10] 上固定数据的拟合。 import paddle import paddle.nn as nn import numpy as np import matplotlib.…...

Vue2: table加载树形数据的踩坑记录

table中需要加载树形数据,如图: 官网给了两个例子,且每个例子中的tree-props都是这么写的: :tree-props="{children: children, hasChildren: hasChildren}" 给我一种错觉,以为数据结构中要同时指定children和hasChildren字段,然而,在非懒加载模式下,数据结…...

全国计算机设计大赛大数据主题赛(和鲸赛道)经验分享

全国计算机设计大赛大数据主题赛(和鲸赛道)经验分享 这是“和鲸杯”辽宁省普通高等学校本科大学生计算机设计竞赛启动会汇报—大数据主题赛的文档总结。想要参加2025年此比赛的可以借鉴。 一、关于我 人工智能专业 计赛相关奖项: 2022年计…...

C# 设计模式(行为型模式):责任链模式

C# 设计模式(行为型模式):责任链模式 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,用于让多个对象有机会处理同一个请求,避免请求发送者与接收者之间的耦合。它通过将请…...

人工智能之机器学习算法

所有的机器学习算法都是要优化的,优化的必要条件是确定优化的目标函数(损失函数),目标函数是根据实际问题(数据)转成的数学公式。 一.线性回归原理推导 (1)回归问题概述 在机器学习的有监督算法中,分类与回归二种情…...

17爬虫:关于DrissionPage相关内容的学习01

概述 前面我们已经大致了解了selenium的用法,DerssionPage同selenium一样,也是一个基于Python的网页自动化工具。 DrissionPage既可以实现网页的自动化操作,也能够实现收发数据包,也可以把两者的功能合二为一。 DressionPage的…...

Ubuntu如何安装jdk并切换到不同的jdk版本

参考:https://www.cnblogs.com/Jakson/articles/4615768.html 摘要 :因为ubuntu 会自带open-jdk预装在系统内,当我们需要在 ubuntu下 安装jdk 的时候 ,发现 即使配置好环境变量后 输入 java -version 版本还是依然没有发生变化,我们需要以下2个步骤切换/usr/local/…...

Python基础语法(上)

目录 一、print函数及常量表达式 1.print函数 2.常量表达式 二、变量 1.定义变量的规则 2.python的动态类型特性 3.字符串 三、注释 四、input函数 1.input函数 2.变量类型转换 五、运算符 1.算数运算符 2.关系运算符 (1)整形的比较 &am…...

k8s系列--docker拉取镜像导入k8s的containerd中

# 确认一下当前集群中正在运行的 Pod 和命名空间 kubectl get pods -A# 示例一:拉取并导入 CoreDNS 镜像 docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.11.1 docker save registry.cn-hangzhou.aliyuncs.com/google_containers/cor…...

深入理解 Android 中的 ComponentInfo

深入理解 Android 中的 ComponentInfo 在 Android 开发中,ComponentInfo 是一个非常重要的类,它用于描述应用程序中的组件信息,包括 Activity、Service、BroadcastReceiver 和 ContentProvider。理解 ComponentInfo 的结构和使用方式&#x…...

阿里云 ECS 服务器绑定多个公网IP

阿里云 ECS 服务器绑定多个公网IP 一、弹性公网IP绑定ECS服务器 单台ECS一般只能直接绑定一个弹性公网IP,但是可以绑定多张弹性网卡,如果把弹性公网IP绑定到弹性网卡上,那么单台ECS就能间接绑定多个弹性公网IP。但有的服务器系统镜像可能不…...

模块化通讯管理机在物联网系统中的应用

安科瑞刘鸿鹏 摘要 随着能源结构转型和智能化电网的推进,电力物联网逐渐成为智能电网的重要组成部分。本文以安科瑞ANet系列智能通信管理机为例,探讨其在电力物联网中的应用,包括数据采集、规约转换、边缘计算、远程控制等技术实践&#…...

Kafka Offset explorer使用

Kafka集群配置好以后以后运维这边先用工具测试一下,便于rd展开后续的工作,本地调试时一般使用Offset explorer工具进行连接 使用SASL(Simple Authentication and Security Layer)验证方式 使用SCRAM-SHA-256(Salted Challenge Response Authentication…...

小程序学习07—— uniapp组件通信props和$emit和插槽语法

目录 一 父组件向子组件传递消息 1.1 props (a)传递静态或动态的 Prop (b)单向数据流 二 子组件通知父组件 2.1 $emit (a)定义自定义事件 (b)绑定自定义事件 三 插槽语法…...

行为模式1.模板方法模式

行为型模式 模板方法模式(Template Method Pattern)命令模式(Command Pattern)迭代器模式(Iterator Pattern)观察者模式(Observer Pattern)中介者模式(Mediator Pattern…...

【模型】Qwen2-VL 服务端UI

1. 前言 最近在测试VLM模型,发现官方的网页demo,代码中视频与图片分辨率可能由于高并发设置的很小,导致达不到预期效果,于是自己研究了一下,搞了一个简单的前端部署,自己在服务器部署了下UI界面&#xff0…...

ImageNet 2.0?自动驾驶数据集迎来自动标注新时代

引言: 3DGS因其渲染速度快和高质量的新视角合成而备受关注。一些研究人员尝试将3DGS应用于驾驶场景的重建。然而,这些方法通常依赖于多种数据类型,如深度图、3D框和移动物体的轨迹。此外,合成图像缺乏标注也限制了其在下游任务中的…...

京东一面:MySQL 主备延迟有哪些坑?主备切换策略

作为一名开发同学,大家对 MySQL 一定不陌生,像常见的 事务特性、隔离级别 、索引等也都是老生常谈。 今天,我们就来聊个深度话题,关于 MySQL 的 高可用 一、什么是高可用? 维基百科定义: 高可用性&#x…...

Linux(Ubuntu24.04)安装Eigen3库

本次安装Eigen3是在WSL2的Ubuntu24.04环境下进行。 Eigen3是一个C模板库,用于线性代数、矩阵运算和数值计算。它提供了一组高性能的矩阵和向量操作,以及常用的线性代数算法,如矩阵分解、特征值求解和最小二乘解等。 1、安装Eigen3 有两种安…...

ABP框架8——仓储的作用及其基础Demo

一、使用仓储的好处 1.提高CRUD接口复用性2.解耦业务逻辑(BLL)和增删改查(CRUD),换ORM特别方便,不需要改应用层,直接改仓储层3.做复杂查询4.事务支持 二、Demo public class BookRepository …...

【Multisim用74ls92和90做六十进制】2022-6-12

缘由Multisim如何用74ls92和90做六十进制-其他-CSDN问答 74LS92、74LS90参考...

利用KPaaS平台提升企业审批流程的透明度

企业的审批流程不仅影响决策效率,还直接关联到组织的透明度和运营效果。传统的审批流程通常由多个环节和系统构成,每一个环节都可能存在信息不对称的现象。例如,某一审批节点的负责人可能并不清楚当前的审批状态,而在其他环节&…...

Python 数据可视化的完整指南

目录 一、为什么选择 Python 进行数据可视化? 二、常用 Python 可视化库及其特点 三、常用图表类型及其代码示例 折线图:用于展示数据随时间或其他连续变量的变化趋势。 柱状图:用于比较不同类别的数据大小。 散点图:用于展示两个变量之间的关系,并发现数据中的模式…...

ZYNQ初识7(zynq_7010)RAM_IP核

学习汇总正点原子bi站教学视频。但由于目前的学习板PL端缺乏时钟晶振,所以需要从PS端调用时钟供给PL端使用,也就造成顶层文件的设置出现一些问题,在IP核创建调用和例化过程中一些功能会受到限制,所以以下仅作汇总参考。 zynq_7000…...

.e01, ..., .e0n的分卷压缩包怎么解压

用BandiZip,这些分卷压缩中还有一个.exe的文件,这个不是可执行文件,是一个解压缩的开头。 安装好bandiZip后,右键这个.exe文件 点击打开就是开始解压了: 最后解压后是这些。然后一个个再次解压....

linux网络管理

网络配置文件 网卡信息文件 :::color3 /etc/sysconfig/network-scripts ::: 配置描述DEVICE网卡设备名-必填BOOTPROTO必填:none,static(静态 IP),dhcp(动态 IP)HWADDRMAC 地址NM_CONTROLLED是否启用Network Manager图形管理工具,建议 noONBOOT是否默认…...

宽带、光猫、路由器、WiFi、光纤之间的关系

1、宽带(Broadband) 1.1 宽带的定义宽带指的是一种高速互联网接入技术,通常包括ADSL、光纤、4G/5G等不同类型的接入方式。宽带的关键特点是能够提供较高的数据传输速率,使得用户可以享受到稳定的上网体验。 1.2 宽带的作用宽带是…...

Momentum Contrast for Unsupervised Visual Representation Learning论文笔记

文章目录 论文地址动量队列对比学习的infoNCE loss为什么需要动量编码器对比学习moco方法中的动量Encoder为什么不能与梯度Encoder完全相同为什么动量编码器和梯度编码器不能完全相同?总结: 我理解,正负样本应该经过同一个encoder&#xff0c…...

linux-26 文件管理(四)install

说一个命令,叫install,man install,install是什么意思?安装,install表示安装的意思,那你猜install是用来干什么的?猜一猜干什么的?安装软件,安装第三方软件,错…...

day-104 组合总和 Ⅳ

思路 动态规划 解题过程 假设dfs(target)表示组成target的组合数,可得转换方程dfs(target)dfs(target-nums[0])dfs(target-nums[1])…以此类推 注意:nums[i]需要小于等于当前的target Code class Solution {public int combinationSum4(int[] nums, i…...

Gitlab-runner 修改默认的builds_dir并使用custom_build_dir配置

gitlab-runner 修改默认的builds_dir并使用custom_build_dir配置 1. 说明2. 实操(以docker执行器为例)2.1 修改默认的builds_dir2.1.1 调整gitlab-runner的配置文件2.1.2 CI文件 2.2 启用custom_build_dir2.2.1 调整gitlab-runner的配置文件2.2.2 CI文件…...

代码随想录算法训练营day21

代码随想录算法训练营 —day21 文章目录 代码随想录算法训练营前言一、669. 修剪二叉搜索树递归法迭代法 二、108.将有序数组转换为二叉搜索树递归法迭代法 三、538.把二叉搜索树转换为累加树递归法 总结 前言 今天是算法营的第21天,希望自己能够坚持下来&#xf…...

苹果系统MacOS下ObjectC建立的App程序访问opencv加载图片程序

前言 苹果系统下使用opencv感觉还是有些不太方便,总是感觉有点受到限制。本博客描述的是在MacOS下建立App程序然后调用opencv显示图片时出现的一些问题并最后解决的一个过程。 一、程序的建立 选择程序的类型: 选择界面模式和编程语言: 其余…...

滴滴工作流引擎Turbo与logicFlow研究

目录 logicFlow turbo 工作流引擎很多,也都提供了前端UI库,但是太过于冗杂了,元数据表都几十个,logincFlow和Turbo的组合提供了轻量化方式,turbo后端代码只有5个元数据表,logicFlow也提供了bpm的相关扩展功能,但缺点是turbo社区不活跃,logicFlow个人认为跟echarts这种…...

快速将索尼手机联系人导出为 HTML 文件

我想将 Sony Xperia 手机上的联系人导出到计算机上进行备份,并在需要时进行编辑。这可以做到吗?如何做到?作为助手我需要下载什么工具吗? 当您的 Android 手机上存储了如此多的重要联系人,而您又不想丢失它们时&#…...

长时间序列预测算法---Informer

目录 一、传统的 Transformer 模型二、Informer原理2.1 Attention计算2.2 “积极”的Q筛选2.2.1 KL散度2.2.2 “懒惰”的q处理 2.3 Encoder结构2.4 Decoder结构2.4.1 Transformer的Decoder操作2.4.2 Informer的Decoder操作 2.5 Informer模型的改进 三、模型应用 时间序列相关参…...

深入理解连接池:从数据库到HTTP的优化之道

在现代应用开发中,高效的资源管理是关键,其中连接池(Connection Pool)技术起到了至关重要的作用。本文将带你深入了解连接池的概念及其在数据库和HTTP通信中的应用,结合 JDBC 与 Druid 的关系,以及 HttpURL…...

LLM(十二)| DeepSeek-V3 技术报告深度解读——开源模型的巅峰之作

近年来,大型语言模型(LLMs)的发展突飞猛进,逐步缩小了与通用人工智能(AGI)的差距。DeepSeek-AI 团队最新发布的 DeepSeek-V3,作为一款强大的混合专家模型(Mixture-of-Experts, MoE&a…...

IIS设置IP+端口号外网无法访问的解决方案

在IIS将站点设置为IP端口访问,假设端口为8080,设好后,服务器上可以访问,外网无法访问。 通常是端口8080没有加入【入站规则】的缘故,将8080端口加入【入站规则】即可,操作如下: 一、ctrlr 输入 …...

Leetcode 最大正方形

java 实现 class Solution {public int maximalSquare(char[][] matrix) {//处理特殊情况if(matrix null || matrix.length 0 || matrix[0].length 0) return 0;int rows matrix.length;int cols matrix[0].length;int[][] dp new int[rows][cols]; //dp[i][j]的含义是以…...

数据结构与算法之动态规划: LeetCode 3105. 最长的严格递增或递减子数组 (Ts版)

最长的严格递增或递减子数组 https://leetcode.cn/problems/longest-strictly-increasing-or-strictly-decreasing-subarray/description/ 描述 给你一个整数数组 nums返回数组 nums 中 严格递增 或 严格递减的最长非空子数组的长度 示例 1 输入:nums [1,4,3,…...

【书籍连载】《软件测试架构实践与精准测试》| 有关软件测试模型的调查结果

各位软件领域的精英们,今天小编邀请你继续深入学习《软件测试架构实践与精准测试》。 《软件测试架构实践与精准测试》是作者李龙(安畅检测首席技术专家)基于软件测试“川模型”的著作。本书结合作者首次提出的软件测试新的模型“川模型”测试…...

我的博客年度之旅:感恩、成长与展望

目录 感恩有你 技能满点 新年新征程 嘿,各位技术大佬、数码潮咖还有屏幕前超爱学习的小伙伴们!当新年的钟声即将敲响,我们站在时光的交汇点上,回首过往,满心感慨;展望未来,豪情满怀。过去的这…...

【RTD MCAL 篇3】 K312 MCU时钟系统配置

【RTD MCAL 篇3】 K312 MCU时钟系统配置 一,文档简介二, 时钟系统理论与配置2.1 K312 时钟系统2.1.1 PLL2.1.2 MUX_0系统2.1.3 MUX_6 时钟输出2.1.4 option B推荐方案 2.2 EB 配置2.2.1 General 配置2.2.2 McuClockSettingConfig配置2.2.2.1 McuFIRC配置…...

力扣28找出字符串中第一个匹配项的下标

class Solution:def strStr(self, haystack: str, needle: str) -> int:# 特殊情况处理if not needle:return 0# 获取 haystack 和 needle 的长度a len(needle)b len(haystack)# 遍历 haystack,检查每个子字符串是否与 needle 匹配for i in range(b - a 1):if…...